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.
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.
Respostas:
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
( \b
corresponde aos limites da palavra e ajuda a evitar falsos positivos nos casos em que "ht" faz parte de outro sinalizador.)
lscpu
é a maneira de verificar.
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
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.
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"
$NUMCORE > $NUMLOG
podemos dizer que o hyperthreading está ativado, certo? Na verdade 2 * $NUMCORE = $NUMLOG
, isso é sempre verdade ou algumas CPUs podem ter 4x mais núcleos?
lscpu
disponível, lscpu
fornecerá as mesmas informações, juntamente com muitos metadados extras, e a saída lscpu
será mais facilmente analisável. mas esta solução funciona e usa apenas /proc/cpuinfo
.
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 Xenserver
onde 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)
/sys/devices/system/cpu/smt/control
. Veja também a resposta do Oscar
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
ht
nos sinalizadores da CPU.
physical id
parece representar o soquete / chip. O core id
parece apontar para o mesmo núcleo físico
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`);'
dmidecode
confiável.
lscpu
nem sempre será confiável. Eu gosto da resposta do scottbb.
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 siblings
nú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
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_list
arquivo 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.
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
...
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))
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.
Muitas advertências e what-if estão nas respostas aqui ... parece que a resposta não é tão óbvia. lscpu
tem 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
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
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
/sys/devices/system/cpu/smt/control
é possível e produz on|off|forceoff|notsupported|notimplemented
.
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
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, lscpu
exibe 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
dmidecode
você ter que ser raiz.