Verificando se o HyperThreading está ativado ou não?


51

Como posso verificar se o hyperthreading está ativado em uma máquina Linux, usando um script perl para verificar isso?

Estou tentando da seguinte maneira:

dmidecode -t processor | grep HTT

Deixe-me saber se estou no caminho certo.


2
para dmidecodevocê ter que ser raiz.
Nils

5
Eu gosto de como todo mundo ignorou a pouco "script perl" ;-)
Samb

Esta deve ser a resposta aceita: unix.stackexchange.com/a/522295/1131
maxschlepzig

Respostas:


27

Notas adicionadas em 8 de julho de 2014: Como apontou Riccardo Murri , minha resposta abaixo mostra apenas se o processador reporta suporte ao hyperthreading. Geralmente, * nix O / S é configurado para ativar o hyperthreading, se suportado. No entanto, para verificar isso de forma programática, veja, por exemplo, a resposta de Nils !

Resposta original de 25 de março de 2012:

Você está realmente no caminho certo :) com

dmidecode -t processor | grep HTT

No Linux, geralmente procuro "ht" na linha "flags" do /proc/cpuinfo. Veja por exemplo

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

ou se você deseja incluir o "ht" no padrão

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

( \bcorresponde aos limites da palavra e ajuda a evitar falsos positivos nos casos em que "ht" faz parte de outro sinalizador.)


19
Isso informará apenas se o processador é compatível com HT, não se o HT está realmente sendo usado.
Riccardo Murri

3
o campo HTT não indica que o processador está realmente com hyperthreading em seus núcleos. verifique o valor de 'irmãos' e 'núcleos da CPU' em / proc / cpuinfo
Silver Moon

@ Silver-Moon Você pode explicar? O dmidecode lê o SMBIOS e deve informar os recursos do processador. Não informa se o hyper-threading é visto ou usado pelo O / S. Mas isso já foi comentado. Veja também Resposta de Nils
xebeche

11
@xebeche na saída do sistema dmidecode mostra "HTT (Multi-threading)", mas meu processador é "core 2 quad Q8400", que não possui hyperthreading. verifique as especificações da intel.
Silver Moon

11
+1 para Riccardo; Eu tenho o HT desativado em um servidor compatível com HT e vejo ele imprimir "HTT". lscpué a maneira de verificar.
Sudo

96

Eu sempre usei o seguinte e observei 'Thread (s) por núcleo:'.

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

Observe, no entanto, que esta técnica falhará se algum processador lógico for desligado com um simples

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

4
Esta é a melhor resposta ainda. Não requer leitura das folhas de chá, muitas informações úteis e nenhum grepping necessário.
MrMas

11
OMG você usou um comando shell para obter sua resposta ?! Isso é tão antigo - -1 por isso. Que tal um bom script Python ??? Você levaria apenas uma tarde para escrever. Como não é Python, outro -1. Mas +3 por brevidade.
Mike S

@ Mike S muito sarcasmo, mas ... A saída do lscpu não está correta quando, digamos, apenas 1 núcleo hiperencadeado está inativo em uma CPU de 4 núcleos (que é um cenário totalmente válido). Porque, então, ele reportará "Thread (s) por núcleo: 1", embora três núcleos sejam realmente com rosca direta (7 threads no total).
Cedric Martin

@ Cedric Martin você notou. :-) ... Oooo! Boa captura ... eu consegui! Tomou uma máquina dupla de 8 núcleos (CPU Dell R620 / E5-2667 v2) ... ela relata 32 CPUs ... Realizada echo 0 > /sys/devices/system/cpu/cpu31/online, agora relatórios lscpu Thread(s) per core: 1. Mau lscpu! Acho que não vou mais usar isso.
Mike S

3
@ Mike S Você ainda pode usar o lscpu , mas não apenas essa linha, eu acho. Usando, digamos, "lscpu -e -a", liste corretamente cada thread e diga se está ativo ou não. Só que "Thread (s) por núcleo" não faz muito sentido quando você pode ativar / desativar segmentos de maneira diferente em cada núcleo.
Cedric Martin

18

Se o número de processadores lógicos for o dobro do número de núcleos que você possui HT. Use o seguinte script para decodificar / 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 > $NUMLOGpodemos dizer que o hyperthreading está ativado, certo? Na verdade 2 * $NUMCORE = $NUMLOG, isso é sempre verdade ou algumas CPUs podem ter 4x mais núcleos?
Tombart

@Tombart Atualmente, o HT é o fator 2. Eu posso imaginar que pode ser mais no futuro. Um núcleo é anotado como físico. O número de núcleos por soquete pode ser derivado de irmãos.
Nils

Se você tiver lscpudisponível, lscpufornecerá as mesmas informações, juntamente com muitos metadados extras, e a saída lscpuserá mais facilmente analisável. mas esta solução funciona e usa apenas /proc/cpuinfo.
Trevor Boyd Smith

8

Os exemplos acima mostram se a CPU é capaz de HT, mas não se estiver sendo usada. O último método funciona, mas não os servidores de soquete duplo e as VMs testadas Xenserveronde não exibe a CPU física, pois não há nenhuma.

Eu achei que essa era a maneira mais fácil e com menos códigos, que também funcionava em todos os meus ambientes de teste. mas requer 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 ################################### "

Acredito que isso funcionará em todas as plataformas e informará se sua CPU é capaz e se está ativada. Pode ser um pouco confuso, mas sou iniciante em scripts. Testei com centos XENSERVER vm, Ubuntu e Openfiler (rpath)


Seu script pode ser muito simplificado apenas lendo /sys/devices/system/cpu/smt/control. Veja também a resposta do Oscar
maxschlepzig

6

Você pode verificar a capacidade HT da CPU com este comando

# grep ht /proc/cpuinfo

Você pode listar a CPU física e lógica vista pelo Kernel com o seguinte comando:

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

Ele fornece esta saída em uma CPU habilitada para HT de núcleo único:

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

Você pode ler o resultado assim:

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

11
Isso informará apenas se o processador é compatível com HT, não se o HT está realmente sendo usado. Os nós cujo processador é compatível com HT, mas onde o HT não está ativado, ainda serão anunciados htnos sinalizadores da CPU.
Riccardo Murri

@RiccardoMurri Tanto quanto eu sei, quando HT está desativado, bandeira ht não aparece no / proc / cpuinfo
Coren

6
Tenho certeza que não é. Eu tenho servidores habilitados para HT e HT, e todos eles mostram o sinalizador ht.
Riccardo Murri

2
Se você tiver um processador Xeon com 4 núcleos, ele será exibido como um ID físico e quatro processadores. Assim, você pode ter vários processadores por ID físico, sem hiper-leitura.
Andomar

2
Eu tenho uma máquina de 2 soquetes, e o physical idparece representar o soquete / chip. O core idparece apontar para o mesmo núcleo físico
Heartinpiece

6

Este liner parece fazer o truque para mim (requer privilégios de root):

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

A saída é:

Core Count: 2
Thread Count: 4

A contagem de threads é o dobro da contagem de núcleos, portanto, tenho o hyperthreading ativado.

Ou se você realmente deseja o seu script perl, conforme solicitado ...

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

11
Eu desliguei o HT em um sistema compatível com Intel, mas o Thread Count retornado com dmidecode é o dobro do Core Count. Parece que mostra se a CPU é compatível com HT, não se HT está ativado ou não.
Dmitri Chubarov

@Dmitri Weird. Acabei de executar isso em um servidor compatível com HT (possui dois Intel Xeon E5-2670 v3) com o hyperthreading desativado, e a contagem de núcleos e threads era a mesma. Não tenho certeza do que causaria a diferença de comportamento. Vou ter que investigar melhor.
billyw

Acabei de executar isso em um Dell R610 com dois processadores X5680, com Hyperthreading desativado, e a contagem de threads é o dobro da contagem de núcleos. a resposta de stephaniea (lscpu) parece funcionar. Verifiquei duas vezes o iDRAC (processador apagado, fora de banda da Dell [para quem não sabe]) e diz que o Hyperthreading está desligado. Então, eu não acho dmidecodeconfiável.
Mike S

Eu verifiquei um Dell 1950 (CPUs x5460, nenhum hyperthreading possível) e o lscpu estava correto. Também um Dell R620 (E5-2690 [v1, acredito]) e estava correto.
Mike S

Mas o comentário de @Cedric Martin em uma das respostas acima mostra que lscpunem sempre será confiável. Eu gosto da resposta do scottbb.
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

Este resultado indica que o HT está ativado, pois o siblingsnúmero (12) é maior que 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 você ler /sys/devices/system/cpu/cpu0/topology/thread_siblings_list, ele retornará uma lista separada por vírgula dos irmãos do thread (ou seja, "núcleos" do Hyperthread)) da CPU 0.

Por exemplo, no meu Xeon de 2 soquetes e 6 núcleos, com o hyperthreading ativado, recebo:

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

Mas depois de desligar o hyperthreading no BIOS, recebo:

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

Supondo que a CPU 0 esteja sempre disponível, verifique o thread_sibling_listarquivo procfs da CPU 0 para mais de um nó, ou procure uma vírgula, ou mesmo algo além disso 0, indicará se o hyperthreading está ativado.


Eu responderia em Perl, mas 1) não conheço Perl e 2) presumo que a solução seja uma linha bastante trivial.


2

No Linux, isso funciona bem:

$ 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  

No exemplo acima, temos 2 soquetes NUMA (SOCKET = 1 ou 2). Temos 16 núcleos físicos (CORE = 0 a 15). Cada CORE possui um hyperthread irmão (por exemplo, CORE = 0 contém CPU 0,16.

Podemos verificar o hyperthread da seguinte maneira:

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

A hierarquia de memória cache é:

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

O lscpu -p fornece uma saída no formato csv para facilitar a análise do programa.

$ 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

Aqui está uma abordagem baseada em python - ela também sugere maneiras de desativá-la, se necessário.

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))

A sugestão para desativar o hyperthreading é subótima - a maneira direta de desativar o hyperthreading é echo off > /sys/devices/system/cpu/smt/control(além de desativá -lo no BIOS). Veja também a resposta do Oscar para uma verificação direta.
maxschlepzig

1

Muitas advertências e what-if estão nas respostas aqui ... parece que a resposta não é tão óbvia. lscputem suas pegadinhas, que se aplicam a qualquer resposta de "núcleos de contagem e processadores lógicos e depois comparar". Como você pode desligar processadores lógicos com um simples comando de eco (... isso pode ser crítico em um ambiente corporativo grande, em que você depende do modo turbo, por exemplo).

Aqui está a minha tentativa; obrigado a @scottbb pela inspiração:

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

Nas minhas máquinas baseadas no Dell Xeon, a lista de irmãos inclui uma vírgula quando o HT está ativado. No meu laptop, ele inclui um hífen (processador i5-3210m). Então, eu estou esperando por pontuação.

Pensamentos? Críticas?

O solicitante pediu perl, então aqui está:

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

Eu usaria apenas grep -q [-.]porque isso é menos para digitar. FWIW, verifiquei vários Xeons / i5 / i7 (incluindo variantes para celular) e nenhum deles tem um hífen no thread_siblings_list. Não é suficiente para cpu0 verificação apenas - assim, algo como isso seria mais robusto: grep -q , /sys/devices/system/cpu/cpu*/topology/thread_siblings_list. No entanto, apenas a grep 1 /sys/devices/system/cpu/smt/active -qé ainda mais direto ao ponto - cf. Resposta de Oscar
maxschlepzig

1

A maneira mais fácil de verificar se o SMT (genérico para HT, que é apenas a marca Intel) está ativo, basta:

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

fornece 0 para inativo ou 1 para ativo

Você pode ativá-lo ou desativá-lo em tempo de execução com:

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

Catting também/sys/devices/system/cpu/smt/control é possível e produz on|off|forceoff|notsupported|notimplemented.
maxschlepzig

0

Melhor verificar lscpu, onde você pode ver "Thread (s) por núcleo: 1", significa apenas um segmento por 1 núcleo.

    # 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 já mencionou lscpu. Eu queria acrescentar um pouco mais a isso.

No meu processador AMD Epyc, sempre que houver um núcleo lógico offline, lscpuexibe uma nova linha adicional chamadaOff-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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.