Verifica se HyperThreading è abilitato o no?


51

Come posso verificare se l'hyperthreading è abilitato su una macchina Linux, usando uno script perl per verificarlo?

Sto provando il seguente modo:

dmidecode -t processor | grep HTT

Fammi sapere se sono sulla buona strada.


2
perché dmidecodedevi essere root.
Nils,

5
Mi piace come tutti
abbiano

Questa dovrebbe essere la risposta accettata: unix.stackexchange.com/a/522295/1131
maxschlepzig

Risposte:


27

Note aggiunte l'8 luglio 2014: Come ha sottolineato Riccardo Murri , la mia risposta sotto mostra solo se il processore riferisce di supportare l'hyperthreading. Generalmente, * nix O / S sono configurati per abilitare l'hyperthreading se supportato. Tuttavia, per verificare effettivamente ciò a livello di codice, vedere ad esempio la risposta di Nils !

---- Risposta originale dal 25 marzo 2012:

Sei davvero sulla strada giusta :) con

dmidecode -t processor | grep HTT

Su Linux, in genere cerco solo "ht" nella riga "flags" di /proc/cpuinfo. Vedi per esempio

grep '^flags\b' /proc/cpuinfo | tail -1

o se si desidera includere "ht" nel modello

grep -o '^flags\b.*: .*\bht\b' /proc/cpuinfo | tail -1

( \bcorrisponde ai limiti delle parole e aiuta a evitare falsi positivi nei casi in cui "ht" fa parte di un'altra bandiera.)


19
Questo ti dirà solo se il processore è in grado di HT, non se HT è effettivamente utilizzato.
Riccardo Murri,

3
il campo HTT non indica che il processore abbia effettivamente hyperthreading nei suoi core. controlla il valore di 'fratelli' e 'cpu core' in / proc / cpuinfo
Silver Moon,

@ Silver-Moon Puoi spiegarmi? dmidecode legge SMBIOS e dovrebbe indicare le capacità del processore. Non dice se l'hyper-thread viene visto o utilizzato dall'hyper-threading. Ma questo è già stato commentato. Vedi anche la risposta di Nils
xebeche,

1
@xebeche sul mio sistema dmidecode mostra "HTT (Multi-threading)" ma il mio processore è "core 2 quad Q8400" che non ha hyperthreading. controllare le specifiche tecniche.
Silver Moon

1
+1 a Riccardo; Ho HT disabilitato su un server abilitato HT e lo vedo stampare "HTT". lscpuè il modo di controllare.
sudo,

96

Ho sempre usato quanto segue e guardato 'Discussioni (s) per core:'.

hostname:~ # lscpu
Architecture:          x86_64
CPU(s):                24
Thread(s) per core:    2                <-- here
Core(s) per socket:    6
CPU socket(s):         2
NUMA node(s):          2
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 44
Stepping:              2
CPU MHz:               1596.000
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              12288K

Nota, tuttavia, questa tecnica fallirà se un processore logico è stato spento con un semplice

echo 0 > /sys/devices/system/cpu/cpuX/online

4
Questa è la risposta migliore ancora. Non richiede la lettura delle foglie di tè, molte informazioni utili e non è richiesto il grepping.
MrMas,

11
OMG hai usato un comando shell per ottenere la tua risposta ?! È così vecchio stile -1 per questo. Che ne dici di un bel copione di Python ??? Ti ci vorrebbe solo un pomeriggio per scrivere. Dal momento che non è Python, un altro -1. Ma +3 per brevità.
Mike S,

@Mike S un sacco di sarcasmo ma ... L'output di lscpu non è corretto quando, diciamo, solo 1 core hyper-thread è inattivo su una CPU a 4 core (che è uno scenario pienamente valido). Perché poi riporterà "Discussioni (s) per core: 1" sebbene 3 core siano effettivamente hyperthread (7 thread in totale).
Cedric Martin,

@Cedric Martin hai notato. :-) ... Oooo! Buona cattura ... l'ho fatto! Ha preso una doppia macchina a 8 core (CPU Dell R620 / E5-2667 v2) ... riporta 32 CPU ... Eseguita echo 0 > /sys/devices/system/cpu/cpu31/online, ora riporta lscpu Thread(s) per core: 1. Cattivo lscpu! Immagino che non lo userò più.
Mike S,

3
@Mike S Puoi ancora usare lscpu , ma immagino non solo quella riga. Usando, diciamo, "lscpu -e -a" elenca correttamente ogni thread e dice se è attivo o meno. È solo che "Thread (s) per core" non ha molto senso quando è possibile abilitare / disabilitare i thread in modo diverso su ciascun core.
Cedric Martin,

18

Se il numero di processori logici è il doppio del numero di core hai HT. Utilizzare il seguente script per decodificare / proc / cpuinfo :

#!/bin/sh
CPUFILE=/proc/cpuinfo
test -f $CPUFILE || exit 1
NUMPHY=`grep "physical id" $CPUFILE | sort -u | wc -l`
NUMLOG=`grep "processor" $CPUFILE | wc -l`
if [ $NUMPHY -eq 1 ]
  then
    echo This system has one physical CPU,
  else
    echo This system has $NUMPHY physical CPUs,
fi
if [ $NUMLOG -gt 1 ]
  then
    echo and $NUMLOG logical CPUs.
    NUMCORE=`grep "core id" $CPUFILE | sort -u | wc -l`
    if [ $NUMCORE -gt 1 ]
      then
        echo For every physical CPU there are $NUMCORE cores.
    fi
  else
    echo and one logical CPU.
fi
echo -n The CPU is a `grep "model name" $CPUFILE | sort -u | cut -d : -f 2-`
echo " with`grep "cache size" $CPUFILE | sort -u | cut -d : -f 2-` cache"

Se $NUMCORE > $NUMLOGpossiamo dire che l'hyperthreading è abilitato, giusto? In realtà sarebbe 2 * $NUMCORE = $NUMLOG, è sempre vero o alcune CPU potrebbero avere 4x più core?
Tombart,

@Tombart Attualmente HT è il fattore 2. Posso immaginare che potrebbe essere più in futuro. Un nucleo è considerato fisico. Il numero di core per socket può essere derivato dai fratelli.
Nils,

Se hai a lscpudisposizione, lscpufornirà le stesse informazioni insieme a molti metadati extra e l'output da lscpusarà più facilmente analizzabile. ma questa soluzione funziona e utilizza solo /proc/cpuinfo.
Trevor Boyd Smith,

8

Gli esempi sopra mostrano se la CPU è in grado di HT, ma non se viene utilizzata. L'ultimo metodo funziona ma non server dual socket e VM testati su Xenserverdove non viene visualizzata la CPU fisica, poiché non ne esistono.

Ho trovato questo il modo più semplice e meno di codice, che ha funzionato anche su tutti i miei ambienti di test. ma richiede bc.

echo "testing ################################### "

nproc=$(grep -i "processor" /proc/cpuinfo | sort -u | wc -l)

phycore=$(cat /proc/cpuinfo | egrep "core id|physical id" | tr -d "\n" | sed s/physical/\\nphysical/g | grep -v ^$ | sort | uniq | wc -l)

if [ -z "$(echo "$phycore *2" | bc | grep $nproc)" ]

then

echo "Does not look like you have HT Enabled"

if [ -z "$( dmidecode -t processor | grep HTT)" ]

 then

echo "HT is also not Possible on this server"

 else

echo "This server is HT Capable,  However it is Disabled"

fi

else

   echo "yay  HT Is working"

fi


echo "testing ################################### "

Credo che funzionerà su tutte le piattaforme e ti dirà se la sua CPU è in grado e se è abilitata. Può essere un po 'confuso, sono un principiante allo scripting però. Ho provato con centos XENSERVER vm, Ubuntu e Openfiler (rpath)


La tua sceneggiatura potrebbe essere molto semplificata semplicemente leggendo /sys/devices/system/cpu/smt/control. Vedi anche la risposta di Oscar
maxschlepzig

6

È possibile verificare la funzionalità HT della CPU con questo comando

# grep ht /proc/cpuinfo

Puoi elencare la CPU fisica e logica vista da Kernel con il seguente comando:

# egrep -i "processor|physical id" /proc/cpuinfo

Fornisce questo output su una CPU abilitata HT single-core:

processor   : 0
physical id : 0
processor   : 1
physical id : 0

Puoi leggere il risultato in questo modo:

processor   : 0 (CPU 0, first logical)
physical id : 0 (CPU 0 is on the first physical)
processor   : 1 (CPU 1, second logical)
physical id : 0 (CPU 1 is on the first physical)
=> It means I have HT enabled

1
Questo ti dirà solo se il processore è in grado di HT, non se HT è effettivamente utilizzato. I nodi il cui processore è abilitato per HT ma in cui HT non è abilitato pubblicizzeranno comunque htnei flag CPU.
Riccardo Murri,

@RiccardoMurri Per quanto ne so, quando HT è disabilitato, la bandiera ht non appare in / proc / cpuinfo
Coren

6
Sono abbastanza sicuro che non lo sia. Ho entrambi i server abilitati HT e disabilitati HT e tutti mostrano il flag ht.
Riccardo Murri,

2
Se hai un processore Xeon con 4 core, mostrerà come un ID fisico e quattro processori. Quindi puoi avere più processori per ID fisico senza hyperheadead.
Andomar,

2
Ho una macchina a 2 socket e physical idsembra rappresentare il socket / chip. Il core idsembra indicare stesso nucleo fisico
Heartinpiece

6

Questa fodera sembra fare il trucco per me (richiede i privilegi di root):

dmidecode -t processor | grep -E '(Core Count|Thread Count)'

L'output è:

Core Count: 2
Thread Count: 4

Il conteggio dei thread è il doppio del conteggio dei core, quindi ho hyperthreading abilitato.

O se vuoi davvero il tuo script perl, come richiesto ...

perl -e 'print grep(/Core Count/ || /Thread Count/, `dmidecode -t processor`);'

1
Ho HT disattivato su un sistema HT basato su Intel, ma il conteggio dei thread restituito con dmidecode è il doppio del conteggio dei core. Sembra che mostra se la CPU è abilitata per HT, non se HT è abilitato o meno.
Dmitri Chubarov,

@Dmitri Weird. Ho appena eseguito questo su un server compatibile con HT (ha due Intel Xeon E5-2670 v3) con hyperthreading disabilitato e il numero di core e thread era lo stesso. Non sono sicuro di cosa causerebbe la differenza di comportamento. Dovrò approfondire.
Billyw,

Ho appena eseguito questo su un Dell R610 con due processori X5680, Hyperthreading disattivato, e il numero di thread è il doppio del numero di core. la risposta di stephaniea (lscpu) sembra funzionare. Ho ricontrollato l'iDRAC (processore Dell spento, fuori banda (per chi non lo sapesse)) e dice che Hyperthreading è spento. Quindi non credo dmidecodesia affidabile.
Mike S,

Ho controllato un Dell 1950 (CPU x5460, nessun hyperthreading possibile) e lscpu era corretto. Anche un Dell R620 (E5-2690 [v1, credo]) ed era corretto.
Mike S,

Ma il commento di @Cedric Martin in una delle risposte sopra mostra che lscpunon sarà sempre affidabile. Mi piace la risposta di Scott.
Mike S,

3
perl -ne'
  $i++ if /^\s*$/;
  push @{$x[$i]}, [/^(.+?) \s*:\s* (.+)/x] if /core|sibling|physical id/; }{
  $r= shift @x; 
  for $i (0..$#$r) {
    $$r[$i][1] .= " ".$$_[$i][1] for @x;
    printf "%-15s: %s\n", @{$$r[$i]};
  }
' /proc/cpuinfo

Questo risultato indica che HT è abilitato poiché il siblingsnumero (12) è maggiore di cpu cores(6)

physical id    : 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1
siblings       : 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12
core id        : 0 1 2 8 9 10 0 1 2 8 9 10 0 1 2 8 9 10 0 1 2 8 9 10
cpu cores      : 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6

2

Se leggi /sys/devices/system/cpu/cpu0/topology/thread_siblings_list, restituirà un elenco separato da virgole dei fratelli thread (ovvero "core" Hyperthread) della CPU 0.

Ad esempio, sul mio Xeon a 6 core a 2 socket, con hyperthreading abilitato ottengo:

cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0,12

Ma dopo aver disattivato l'hyperthreading nel BIOS, ottengo:

cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0

Supponendo che CPU 0 sarà sempre disponibile, quindi controllando il thread_sibling_listfile procfs della CPU 0 per più di un nodo, o cercando una virgola, o anche solo qualcosa di più 0, indicherà se l'hyperthreading è abilitato.


Risponderei in Perl, ma 1) Non conosco Perl e 2) Presumo che la soluzione sia piuttosto banale.


2

Su Linux funziona bene:

$ lscpu -e  
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE  
0   0    0      0    0:0:0:0       yes  
1   0    0      1    1:1:1:0       yes  
2   0    0      2    2:2:2:0       yes  
3   0    0      3    3:3:3:0       yes  
4   0    0      4    4:4:4:0       yes  
5   0    0      5    5:5:5:0       yes  
6   0    0      6    6:6:6:0       yes  
7   0    0      7    7:7:7:0       yes  
8   1    1      8    8:8:8:1       yes  
9   1    1      9    9:9:9:1       yes  
10  1    1      10   10:10:10:1    yes  
11  1    1      11   11:11:11:1    yes  
12  1    1      12   12:12:12:1    yes  
13  1    1      13   13:13:13:1    yes  
14  1    1      14   14:14:14:1    yes  
15  1    1      15   15:15:15:1    yes  
16  0    0      0    0:0:0:0       yes  
17  0    0      1    1:1:1:0       yes   
18  0    0      2    2:2:2:0       yes  
19  0    0      3    3:3:3:0       yes  
20  0    0      4    4:4:4:0       yes  
21  0    0      5    5:5:5:0       yes  
22  0    0      6    6:6:6:0       yes  
23  0    0      7    7:7:7:0       yes  
24  1    1      8    8:8:8:1       yes  
25  1    1      9    9:9:9:1       yes  
26  1    1      10   10:10:10:1    yes  
27  1    1      11   11:11:11:1    yes  
28  1    1      12   12:12:12:1    yes  
29  1    1      13   13:13:13:1    yes  
30  1    1      14   14:14:14:1    yes  
31  1    1      15   15:15:15:1    yes  

Nell'esempio sopra, abbiamo 2 socket NUMA (SOCKET = 1 o 2). Abbiamo 16 core fisici (CORE = da 0 a 15). Ogni CORE ha un hyperthread di pari livello (ad esempio CORE = 0 contiene CPU 0,16.

Possiamo verificare l'hyperthread in questo modo:

$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list  
0,16

La gerarchia della memoria cache è:

CPU 0 --> L1D_0|L1I_0 -> L2_0 -> L3_0  
          ^                      ^
CPU 16 ---|                      |     
                                 |         
CPU 1 --> L1D_1|L1I_1 -> L2_1 ---> 
          ^    
CPU 17 ---|   
...    

lscpu -p fornisce un output in formato CSV per un facile analisi del programma.

$ lscpu -p  
# The following is the parsable format, which can be fed to other
# programs. Each different item in every column has an unique ID
# starting from zero.
# CPU,Core,Socket,Node,,L1d,L1i,L2,L3
0,0,0,0,,0,0,0,0
1,1,0,0,,1,1,1,0
2,2,0,0,,2,2,2,0
3,3,0,0,,3,3,3,0
4,4,0,0,,4,4,4,0
...

2

Ecco un approccio basato su Python - suggerisce anche modi per disabilitarlo, se necessario.

import re    

total_logical_cpus = 0
total_physical_cpus = 0
total_cores = 0

logical_cpus = {}
physical_cpus = {}
cores = {}

hyperthreading = False

for line in open('/proc/cpuinfo').readlines():
    if re.match('processor', line):
        cpu = int(line.split()[2])

        if cpu not in logical_cpus:
            logical_cpus[cpu] = []
            total_logical_cpus += 1

    if re.match('physical id', line):
        phys_id = int(line.split()[3])

        if phys_id not in physical_cpus:
            physical_cpus[phys_id] = []
            total_physical_cpus += 1

    if re.match('core id', line):
        core = int(line.split()[3])

        if core not in cores:
            cores[core] = []
            total_cores += 1

        cores[core].append(cpu)

if (total_cores * total_physical_cpus) * 2 == total_logical_cpus:
    hyperthreading = True

print("  This system has %d physical CPUs" % total_physical_cpus)
print("  This system has %d cores per physical CPU" % total_cores)
print("  This system has %d total cores" % (total_cores * total_physical_cpus))
print("  This system has %d logical CPUs" % total_logical_cpus)

if hyperthreading:
    print("  HT detected, if you want to disable it:")
    print("  Edit your grub config and add 'noht'")
    print("  -OR- disable hyperthreading in the BIOS")
    print("  -OR- try the following to offline those CPUs:")

    for c in cores:
        for p, val in enumerate(cores[c]):
            if p > 0:
                print("    echo 0 > /sys/devices/system/cpu/cpu%d/online" % (val))

Il suggerimento per disabilitare l'hyperthreading è subottimale - il modo diretto per disabilitare l'hyperthreading è echo off > /sys/devices/system/cpu/smt/control(oltre a disattivarlo nel BIOS). Vedi anche la risposta di Oscar per un controllo diretto.
maxschlepzig,

1

Ci sono un sacco di avvertimenti e what-if nelle risposte qui ... sembra che la risposta non sia così ovvia. lscpuha i suoi gotcha, che si applicano a qualsiasi risposta "conta core e processori logici, quindi confronta". Perché puoi spegnere i processori logici con un semplice comando echo (... questo potrebbe essere fondamentale in un grande ambiente aziendale in cui dipendi dalla modalità turbo, per esempio).

Ecco il mio tentativo; grazie a @scottbb per l'ispirazione:

printf "HT is "; egrep -q [:punct:] /sys/devices/system/cpu/cpu0/topology/thread_siblings_list && echo on || echo off 

Sui miei computer basati su Dell Xeon, l'elenco dei fratelli include una virgola quando HT è attivo. Sul mio laptop, include un trattino (processore i5-3210m). Quindi sto preparando la punteggiatura.

Pensieri? Critiche?

Il richiedente ha chiesto il perl, quindi eccoti qui:

perl -ane 'chomp; print "Hyperthreading is "; if (/\D/) { print "ON\n" } else { print "OFF\n" }' < /sys/devices/system/cpu/cpu0/topology/thread_siblings_list

Vorrei solo usare grep -q [-.]come questo è meno da digitare. FWIW, ho controllato diversi Xeons / i5 / i7 (comprese le varianti mobili) e nessuno di loro ha un trattino in thread_siblings_list. Non è sufficiente solo cpu0 check - in tal modo, una cosa del genere sarebbe più robusto: grep -q , /sys/devices/system/cpu/cpu*/topology/thread_siblings_list. Tuttavia, solo a grep 1 /sys/devices/system/cpu/smt/active -qè ancora di più al punto - cfr. Risposta di Oscar
maxschlepzig

1

Il modo più semplice per verificare se è attivo SMT (generico per HT, che è solo il marchio Intel):

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

ti dà 0 per inattivo o 1 per attivo

Puoi effettivamente accenderlo o spegnerlo in fase di esecuzione con:

echo [on|off] > /sys/devices/system/cpu/smt/control

Anche l'allevamento /sys/devices/system/cpu/smt/controlè possibile e produce on|off|forceoff|notsupported|notimplemented.
maxschlepzig,

0

Meglio controllare lscpu, dove puoi vedere "Discussioni (s) per core: 1", significa solo un thread per 1 core.

    # lscpu
    Architecture:          x86_64
    CPU op-mode(s):        32-bit, 64-bit
    Byte Order:            Little Endian

CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    1
Core(s) per socket:    4
Socket(s):             2
NUMA node(s):          2
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 63
Model name:            Intel(R) Xeon(R) CPU E5-2623 v3 @ 3.00GHz
Stepping:              2
CPU MHz:               1200.000
BogoMIPS:              5992.82
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              10240K
NUMA node0 CPU(s):     0,1,4,5
NUMA node1 CPU(s):     2,3,6,7

0

Stephaniea ha già menzionato lscpu. Volevo aggiungere un po 'di più a quello.

Sul mio processore AMD Epyc, ogni volta che c'è un core logico offline, lscpuvisualizza una nuova linea aggiuntiva chiamataOff-line CPU(s) list:

# echo 0 > /sys/devices/system/cpu/cpu9/online
# echo 0 > /sys/devices/system/cpu/cpu16/online
# 
#lscpu
CPU(s):                64
On-line CPU(s) list:   0-8,10-15,17-63
Off-line CPU(s) list:  9,16
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.