Disabilita hyperthreading da Linux (nessun accesso al BIOS)


26

Ho un sistema che esegue un'applicazione di trading finanziario in una struttura remota. Non ho accesso a ILO / DRAC, ma devo disabilitare l'hyperthreading. Il sistema funziona con CPU hex-core Intel Westmere 3.33GHz X5680. Posso riavviare, ma voglio assicurarmi che il sistema non abiliti l'hyperthreading a causa di problemi di prestazioni. C'è un modo pulito per farlo da Linux?

Modifica: la nohtdirettiva aggiunta alla riga di comando di avvio del kernel non ha funzionato. Lo stesso per RHEL.

Vedi: https://bugzilla.redhat.com/show_bug.cgi?id=440321#c9

Risposte:


21

Puoi farlo in fase di esecuzione se vuoi. Ho trovato una bella soluzione descritta qui: http://www.absolutelytech.com/2011/08/01/how-to-disable-cpu-cores-in-linux/

Passaggio 1: identificare le CPU linux che si desidera spegnere:

cat /proc/cpuinfo

Cerca le CPU che hanno lo stesso "ID core", vuoi spegnere una di ciascuna coppia.

Step 2: Spegni le CPU hyperthreading (nel mio caso le ultime quattro delle 8 "CPU" totali viste da Linux)

echo 0 > /sys/devices/system/cpu/cpu4/online
echo 0 > /sys/devices/system/cpu/cpu5/online
echo 0 > /sys/devices/system/cpu/cpu6/online
echo 0 > /sys/devices/system/cpu/cpu7/online

Potresti impostare uno script che esegui subito dopo l'avvio del sistema.


1
Funziona quasi come mi aspettavo. i core virtuali sono disabilitati, ora quando eseguo un thread che consuma cpu carica il core fisico del 100%. Ma l'utilizzo sysbench --num-threads=1 --test=cpu runcon diversi num-thread e HT attivato e disattivato indica che la disabilitazione di HT diminuisce la prestazione quando ci sono molti thread e anche se c'è solo un thread non è utile disattivare HT. Quindi suggerisco di lasciarlo così com'è: è ottimale.
Sergey P. aka azzurro

Sapresti qual è il comando per riaccenderli? Il link all'inizio della tua risposta è morto ~. Grazie!
user189035

@ user189035: echo 1invece di echo 0riaccenderli.
Peter Cordes,

@ SergeyP.akaazure, penso per un'applicazione di servizi finanziari, il motivo principale per disattivare HT non è la prestazione, ma la sicurezza.
Simon Richter,

@SimonRichter All'epoca in cui questa domanda era stata originariamente scritta, era davvero una prestazione. SMT / HT non era altrettanto efficace in alcuni carichi di lavoro sulle CPU di quell'epoca. La cosa Meltdown / Spectre e gli attacchi Foreshadow più recenti sono avvenuti anni dopo.
Michael Hampton

14

Uno script per disabilitare l'hyperthreading all'avvio della macchina ...

Per disabilitare l'hyperthreading includo uno script sulla macchina /etc/rc.local. Non è perfettamente pulito, ma è facile da installare, indipendente dall'architettura della CPU e dovrebbe funzionare su qualsiasi distribuzione linux moderna.

nano /etc/rc.local

    # place this near the end before the "exit 0"

    for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
        CPUID=$(basename $CPU)
        echo "CPU: $CPUID";
        if test -e $CPU/online; then
                echo "1" > $CPU/online; 
        fi;
        COREID="$(cat $CPU/topology/core_id)";
        eval "COREENABLE=\"\${core${COREID}enable}\"";
        if ${COREENABLE:-true}; then        
                echo "${CPU} core=${CORE} -> enable"
                eval "core${COREID}enable='false'";
        else
                echo "$CPU core=${CORE} -> disable"; 
                echo "0" > "$CPU/online"; 
        fi; 
    done;    

Come funziona?

È possibile accedere alle informazioni e ai controlli del kernel Linux come file nella directory / sys nelle moderne distribuzioni di Linux. Per esempio:

/ sys / devices / system / cpu / cpu3 contiene le informazioni del kernel e i controlli per la CPU logica 3.

cat / sys / devices / system / cpu / cpu3 / topology / core_id mostrerà il numero di core a cui appartiene questa CPU logica.

echo "0"> / sys / devices / system / cpu / cpu3 / online consente di disabilitare la CPU logica 3.

Perché funziona

Non so esattamente perché ... ma il sistema diventa più reattivo con l'hyperthreading disattivato (sul mio notebook i5 e server Xeon di massa con oltre 60 core). Immagino che abbia a che fare con le cache per CPU, l'allocazione di memoria per CPU, l'allocazione dello scheduler della CPU e le iterazioni complesse con priorità di processo. Penso che i vantaggi dell'hyperthreading siano superiori alla complessità di creare programmatori CPU che sanno come usarlo.

Per me, il problema con l'hyperthreading è: se avessi tanti thread ad alta intensità di CPU quanti sono i core logici, avrò rapidi cambi di contesto per le attività intensive della cpu, ma costosi per le attività in background poiché l'hyperthreading totalmente consumato dal compiti intensivi della CPU. D'altra parte, se avvio tanti thread ad alta intensità di CPU quanti sono i core fisici, non avrò alcun cambio di contesto per quelle attività e cambi di contesto rapidi per le attività in background. Sembra buono, ma le attività in background troveranno processori logici gratuiti e verranno eseguiti quasi immediatamente. È come se fossero performance in tempo reale (bello -20).

Nel primo scenario l'hyperthreading è uselles, le attività in background useranno costosi switch di contesto perché ho massimizzato l'hyperthreading con la normale elaborazione. Il secondo è irripetibile perché fino al 50% della mia potenza della cpu è prioritario rispetto alle attività in background.

I compiti "ad alta intensità di cpu" di cui sto parlando sono server di mining e autorizzazione di dati di intelligenza artificiale (il mio lavoro). Rendering di Blender in computer e cluster economici (per disegnare la mia casa futura).

Inoltre, si tratta di congetture.

Ho l'impressione che sia migliore, ma potrebbe non esserlo.


Penso che il mio scriptlet sia un po 'più facile da seguire.
Paul M

9

Per kernel molto vecchi (Linux 2.6.9 o giù di lì), aggiungi il parametro noht al kernel all'avvio.

Questa opzione della riga di comando del kernel è stata rimossa almeno da Linux 2.6.18 .


Da http://www.faqs.org/docs/Linux-HOWTO/BootPrompt-HOWTO.html :

The `noht' Argument

This will disable hyper-threading on intel processors that have this feature. 

Se usi lilo, modifica /etc/lilo.conf (ed esegui successivamente lilo) o se usi grub, modifica il tuo /boot/grub/menu.lst.


Funzionalmente equivale a disabilitare HT nel BIOS?
ewwhite,

Non lo so per certo, ma sì, non mi aspetterei che niente equivale a disabilitarlo sul BIOS.
ricorre il

2
Questo è un sistema Gentoo. Ho provato la nohtvoce nella riga di comando del kernel grub. Il sistema non ha rispettato il nohtcomando. Lo stesso per RHEL. Vedi: bugzilla.redhat.com/show_bug.cgi?id=440321#c9
ewwhite

1
Questo è obsoleto almeno da Linux 2.6.18 . L' nohtopzione del kernel è stata rimossa. Questo è un peccato, perché Linux abilita una soluzione alternativa per alcuni errata perf-counter Haswell (BJ122, BV98, HSD29) solo se HT è attivo , e questo accade prima ancora che initramfs sia caricato.
Peter Cordes,

9

È possibile utilizzare "thread_siblings_list" per ciascun core per disattivare il secondo core nella coppia HT.

La seguente pipeline di comandi è caotica, non ottimizzata, e si spera in questo modo per rendere più facile la comprensione.

cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | \
awk -F, '{print $2}' | \
sort -n | \
uniq | \
( while read X ; do echo $X ; echo 0 > /sys/devices/system/cpu/cpu$X/online ; done )

quindi, prendi tutti gli elenchi dei fratelli thread, estrai la seconda CPU per ogni coppia, ottieni un elenco univoco e poi spegnili.

ha senso?

se faccio "cat / proc / cpuinfo" dopo aver eseguito quanto sopra, il numero di core si dimezza.


Questa è un'ottima risposta Ho dovuto modificarlo come segue per funzionare per i miei scopi: echo 0 > /sys/devices/system/cpu/cpu$X/onlinediventaecho 0 | sudo tee /sys/devices/system/cpu/cpu$X/online
carbocation

5

I kernel più recenti forniscono un controllo Multithreading simultaneo (SMT).

È possibile controllare lo stato di SMT con;

cat /sys/devices/system/cpu/smt/active

Cambia lo stato con

echo off > /sys/devices/system/cpu/smt/control

Le opzioni sono;

  • su
  • via
  • forceoff

Abbiamo verificato questo con Linux Kernel 4.4.0


Ciao Nick e benvenuto nel sito. Le informazioni sui test (e sulla versione) sono piuttosto preziose.
kubanczyk,

Eccellente, testato su Ubuntu 16.04.6 LTS
Elder Geek,

4

La risposta di Lukas è buona, ma in realtà non funziona per disabilitare HT perché l'ID core non può servire per l'identificazione dei fratelli HT. Questo script funziona invece:

#!/bin/bash
for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
    CPUID=`basename $CPU | cut -b4-`
    echo -en "CPU: $CPUID\t"
    [ -e $CPU/online ] && echo "1" > $CPU/online
    THREAD1=`cat $CPU/topology/thread_siblings_list | cut -f1 -d,`
    if [ $CPUID = $THREAD1 ]; then
        echo "-> enable"
        [ -e $CPU/online ] && echo "1" > $CPU/online
    else
        echo "-> disable"
        echo "0" > $CPU/online
    fi
done

la tua sceneggiatura è una mia variante. dovremmo verificare cosa succede se hai più CPU, per essere sicuro.
Paul M,

@PaulM Ecco dove l'ho testato e usato per i miei scopi: sistema Haswell a 2 socket.
Anton,

0

Ho dovuto aspettare fino a quando potevo entrare nell'ILO / Drac. I parametri di avvio del kernel non funzionano con le attuali distribuzioni Linux.


0

Nel pacchetto libsmbios-bin (Debian, Ubuntu, ecc.), Hai i binari isCmosTokenActive e activCmosToken. Insieme all'elenco dei token , puoi quindi provare qualcosa del genere:

# isCmosTokenActive 0x00d1 # CPU_Hyperthreading_Enable
[...] Type 0x00d1  Location 0x46 AND(fe) OR(0)  BITFIELD: 1
# isCmosTokenActive 0x00d2 # CPU_Hyperthreading_Disable
[....] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 0

Quindi attivare il token CPU_Hyperthreading_Disable:

# activateCmosToken 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 1

Verificare:

# isCmosTokenActive 0x00d1 # CPU_Hyperthreading_Enable
[...] Type 0x00d1  Location 0x46 AND(fe) OR(0)  BITFIELD: 0
# isCmosTokenActive 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 1

Ora, la grande domanda è se hai semplicemente bisogno di un riavvio o meno per far sì che questo abbia effetto, o se è necessario un ciclo di accensione completo. Provalo e guarda come va!


0

Sulla base delle informazioni fornite da Paul M qui, lo "scrivo" in questo modo:

fgrep , /sys/devices/system/cpu/cpu*/topology/thread_siblings_list |
cut -d, -f2 | sort -u |
sudo xargs -rI, sh -c 'echo 0 > /sys/devices/system/cpu/cpu,/online'

Ovviamente non disattiva l'hyper-threading nello stesso senso in cui farebbe armeggiare con il BIOS , in pratica dice solo all'utilità di pianificazione del kernel di non usare alcuni core perché sappiamo che sono falsi.

Il software che ha assunto la sua ipotesi sulla base dello stato /proco del /syssottosistema precedente potrebbe essere ancora in esecuzione non ottimale o addirittura non riuscire a causa di questa modifica del tempo di esecuzione, quindi potrebbe essere necessario il suo riavvio. Ad esempio, ho notato che irqbalanceera incline a fallire in quelle circostanze.


0

Disabilita HT:

echo 0 |sudo tee /sys/devices/system/cpu/cpu{4..7}/online

Abilita HT:

echo 1 |sudo tee /sys/devices/system/cpu/cpu{4..7}/online

Nota: questo non disabilita realmente HyperThreading ma disabilita i core "falsi" ottenendo quasi lo stesso risultato.


Mi piace il modo in cui stai usando tee, ma questo non è ancora in grado di fornire una risposta reale alla domanda. Tali comandi si applicano solo a specifiche configurazioni hardware e possono avere effetti indesiderati su altre configurazioni hardware. E una spiegazione di ciò che fanno quei comandi è completamente assente.
Kasperd,

Dato che 0 significa off e 1 significa on, ho pensato che fosse facile capire che il primo spegne 4 core (del falso 8 su un quandocore con hyperthreading attivo) e il secondo li riaccende ... Se hai un DUAL core quel numero deve essere {3,4} invece di {4..7} Se usi un ottacore deve essere {8..15}
Zibri

0

Vecchio argomento, ma aveva motivo di provare questo esperimento. Innanzitutto, non sono affatto sicuro che disabilitare le CPU (leggermente false) in fase di esecuzione sia veramente equivalente a disabilitare Hyperthreading all'avvio. Detto questo, ho visto un piccolo aumento delle prestazioni nella nostra applicazione. (Ma non abbastanza da mantenere.)

Utilizzato il valore thread_siblings (comune alle CPU hyperthreaded) come chiave per abilitare / disabilitare:

for i in /sys/devices/system/cpu/cpu[0-9]* 
do echo "$(cat $i/topology/thread_siblings) $i" 
done | 
awk '{v = (a[$1] ? 0 : 1); a[$1] = 1; print "echo " v " > " $2 "/online"}' | 
sudo sh 

Provate il comando w / o la finale sh sudo per verificare il corretto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.