Проверка, включена ли HyperThreading или нет?


51

Как я могу проверить, включена ли гиперпоточность на машине с Linux, используя для этого скрипт perl?

Я пытаюсь следующим образом:

dmidecode -t processor | grep HTT

Дайте мне знать, если я на правильном пути.


2
потому что dmidecodeвы должны быть пользователем root.
Нильс

5
Мне нравится, как все игнорировали бит "perl script" ;-)
SamB

Это должен быть принятый ответ: unix.stackexchange.com/a/522295/1131
maxschlepzig

Ответы:


27

Примечания добавлены 8 июля 2014 года. Как отметил Риккардо Мурри , мой ответ ниже показывает только то, сообщает ли процессор о поддержке гиперпоточности. Как правило, * nix O / S настроены для включения гиперпоточности, если это поддерживается. Однако, чтобы проверить это программно, посмотрите, например , ответ Нильса !

---- Оригинальный ответ от 25 марта 2012 г .:

Вы действительно на правильном пути :) с

dmidecode -t processor | grep HTT

В Linux я обычно просто ищу «ht» в строке «flags» /proc/cpuinfo. Смотри например

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

или если вы хотите включить "ht" в шаблон

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

( \bСоответствует границам слова и помогает избежать ложных срабатываний в случаях, когда «ht» является частью другого флага.)


19
Это только скажет вам, если процессор поддерживает HT, но не использует ли HT на самом деле.
Риккардо Мурри

3
поле HTT не указывает на то, что процессор фактически имеет гиперпоточность в своих ядрах. проверьте значение 'siblings' и 'cores' в / proc / cpuinfo
Silver Moon

@ Silver-Moon Можете ли вы объяснить? dmidecode читает SMBIOS и должен сообщать о возможностях процессора. Он не сообщает, является ли гиперпоточность видимой или используемой O / S. Но это уже прокомментировано. Смотрите также ответ Нильса
xebeche

1
@xebeche в моей системе вывод dmidecode показывает "HTT (многопоточность)", но мой процессор "core 2 quad Q8400", который не имеет гиперпоточности. проверьте спецификации Intel.
Серебряная луна

1
+1 к Риккардо; Я отключил HT на сервере с поддержкой HT, и я вижу, что он печатает «HTT». lscpuэто способ проверить.
Судо

96

Я всегда просто использовал следующее и смотрел на «Thread (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

Обратите внимание, однако, что этот метод не будет работать, если какой-либо логический процессор был отключен с помощью простого

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

4
Это лучший ответ еще. Это не требует чтения чайных листьев, большого количества полезной информации и не требует опечаток.
MrMas

11
О боже, вы использовали команду оболочки, чтобы получить ответ ?! Это так старая школа - -1 за это. А как насчет хорошего сценария Python ??? Это займет всего полдня, чтобы написать. Поскольку это не Python, другой -1. Но +3 для краткости.
Майк С

@Mike S много сарказма, но ... Вывод lscpu не корректен, когда, скажем, только 1 гиперпоточное ядро ​​не работает на 4-ядерном процессоре (что является полностью допустимым сценарием). Потому что тогда он сообщит "Thread (s) per core: 1", хотя на самом деле 3 ядра на самом деле являются гиперпоточными (всего 7 потоков).
Седрик Мартин

@ Седрик Мартин, ты заметил. :-) ... Оооо! Хороший улов ... Я сделал это! Взял двойную 8-ядерную машину (Dell R620 / E5-2667 v2 CPU) ... он сообщает о 32 CPU ... Выполнено echo 0 > /sys/devices/system/cpu/cpu31/online, теперь lscpu сообщает Thread(s) per core: 1. Плохо lscpu! Думаю, я больше не буду этим пользоваться.
Майк С

3
@Mike S Вы все еще можете использовать lscpu , но я думаю, что это не та строка. Использование, скажем, «lscpu -e -a» правильно выводит список каждого потока и сообщает, активен он или нет. Просто «Thread (s) per core» не имеет особого смысла, когда вы можете по-разному включать / отключать потоки для каждого ядра.
Седрик Мартин

18

Если количество логических процессоров в два раза больше ядер, у вас есть HT. Используйте следующий скрипт для декодирования / 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мы можем сказать, что гиперпоточность включена, верно? На самом деле это так 2 * $NUMCORE = $NUMLOG, всегда ли это так, или у некоторых процессоров может быть в 4 раза больше ядер?
Томбарт

@ Томбарт В настоящее время HT является фактором 2. Я могу представить, что в будущем это может быть больше. Ядро отмечено как физическое. Количество ядер на сокет может быть получено из братьев и сестер.
Нильс

Если у вас есть lscpuдоступ, вы lscpuполучите ту же информацию, а также множество дополнительных метаданных, и результаты из них lscpuбудут более легко разбираться. но это решение работает и только использует /proc/cpuinfo.
Тревор Бойд Смит

8

Приведенные выше примеры показывают, способен ли ЦП поддерживать HT, но нет, если он используется. Последний способ работает, но не тестируются серверы с двумя сокетами и виртуальные машины, на Xenserverкоторых он не отображает физический процессор, поскольку их нет.

Я обнаружил, что это самый простой и менее кодовый способ, который также работал во всех моих тестовых средах. но требует 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 ################################### "

Я считаю, что это будет работать на всех платформах, и скажет вам, если его процессор способен, и если он включен. Может быть, немного грязно, я начинающий в сценарии, хотя. Я тестировал с помощью Centos XENSERVER vm, Ubuntu и Openfiler (rpath)


Ваш сценарий может быть значительно упрощен, просто читая /sys/devices/system/cpu/smt/control. Смотрите также ответ Оскара
maxschlepzig

6

С помощью этой команды вы можете проверить возможности HT процессора.

# grep ht /proc/cpuinfo

Вы можете перечислить физический и логический процессор, видимый ядром, с помощью следующей команды:

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

Это дает этот вывод на одноядерный процессор с поддержкой HT:

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

Вы можете прочитать результат так:

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
Это только скажет вам, если процессор поддерживает HT, но не использует ли HT на самом деле. Узлы, процессор которых поддерживает HT, но где HT не включен, будут по-прежнему размещаться htв флагах процессора.
Риккардо Мурри

@RiccardoMurri Насколько я знаю, когда HT отключен, флаг ht не появляется в / proc / cpuinfo
Coren

6
Я уверен, что это не так. У меня есть и HT-включенные и HT-отключенные серверы, и все они показывают флаг ht.
Риккардо Мурри

2
Если у вас процессор Xeon с 4 ядрами, он будет отображаться как один физический идентификатор и четыре процессора. Таким образом, вы можете иметь несколько процессоров для каждого физического идентификатора без гипертрединга.
Andomar

2
У меня есть машина с 2 сокетами, и physical idкажется, что представляет сокет / чип. core id, Кажется, указывают на то же физическое ядро
Heartinpiece

6

Этот лайнер, кажется, помогает мне (требует привилегий root):

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

Выход:

Core Count: 2
Thread Count: 4

Счетчик потоков вдвое больше ядра, поэтому у меня включена поддержка гиперпоточности.

Или, если вы действительно хотите свой Perl-скрипт, как и просили ...

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

1
Я выключил HT в системе с поддержкой Intel на базе HT, но число потоков, возвращаемое с помощью dmidecode, вдвое превышает число ядер. Похоже, он показывает, поддерживает ли процессор HT, а не включен или нет HT.
Дмитрий Чубаров

@ Дмитрий Странный. Я только что запустил это на сервере с поддержкой HT (имеет два Intel Xeon E5-2670 v3) с отключенной гиперпоточностью, и количество ядер и потоков было одинаковым. Я не уверен, что вызвало бы разницу в поведении. Я должен смотреть дальше в это.
Billyw

Я только что запустил это на Dell R610 с двумя процессорами X5680, отключив Hyperthreading, и число потоков в два раза превышает число ядер. Ответ Стефании (lscpu), кажется, работает. Я дважды проверил iDRAC (выключение Dell, внеполосный процессор [для тех, кто не в курсе]), и он говорит, что Hyperthreading выключен. Поэтому я не думаю, что dmidecodeэто надежно.
Майк С

Я проверил Dell 1950 (процессоры x5460, гиперпоточность невозможна), и lscpu оказался верным. Также Dell R620 (E5-2690 [v1, я считаю]), и это было правильно.
Майк С

Но комментарий @Cedric Martin в одном из ответов выше показывает, что lscpuэто не всегда будет надежно. Мне нравится ответ Скоттбба.
Майк С

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

Этот результат указывает, что HT включен, поскольку siblingsчисло (12) больше, чем 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

Если вы прочитаете /sys/devices/system/cpu/cpu0/topology/thread_siblings_list, он вернет разделенный запятыми список родных элементов потока (т. Е. Hyperthread "cores") CPU 0.

Например, на моем 2-сокетном 6-ядерном Xeon с включенной гиперпоточностью я получаю:

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

Но после отключения гиперпоточности в BIOS я получаю:

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

Предполагая, что CPU 0 будет всегда доступен, тогда проверка thread_sibling_listфайла procfs CPU 0 для более чем одного узла, или поиск запятой, или даже просто чего-то большего 0, покажет, включена ли гиперпоточность.


Я бы ответил на Perl, но 1) я не знаю Perl, и 2) я полагаю, что решение довольно тривиально.


2

На Linux это работает хорошо:

$ 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  

В приведенном выше примере у нас есть 2 разъема NUMA (SOCKET = 1 или 2). У нас 16 физических ядер (CORE = от 0 до 15). Каждый CORE имеет одноуровневую гиперпоточность (например, CORE = 0 содержит CPU 0,16.

Мы можем проверить Hyperthread следующим образом:

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

Иерархия кеш-памяти:

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

lscpu -p дает вывод в формате csv для простого анализа программы.

$ 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

Вот подход на основе Python - он также предлагает способы его отключения, если это необходимо.

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(помимо отключения его в BIOS). Смотрите также ответ Оскара для прямой проверки.
maxschlepzig

1

Здесь много предостережений и что-если в ответах ... кажется, что ответ не так очевиден. lscpuимеет свои гоча, которые применяются к любому ответу «подсчитать количество ядер и логических процессоров, а затем сравнить». Потому что вы можете отключить логические процессоры с помощью простой команды echo (... это может иметь решающее значение в большой корпоративной среде, где вы, например, зависите от турбо-режима).

Вот моя попытка; спасибо @scottbb за вдохновение:

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

На моих компьютерах с процессором Dell Xeon список родственников включает запятую при включенном HT. На моем ноутбуке он содержит дефис (процессор i5-3210m). Так что я исправляю пунктуацию.

Мысли? Критицизмы?

Запрашивающий запросил Perl, так что вы идете:

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 [-.]как это меньше, чтобы напечатать. FWIW, я проверил несколько Xeons / i5 / i7 (включая мобильные варианты), и ни у одного из них нет дефиса в thread_siblings_list. Это не достаточно , чтобы просто проверить CPU0 - таким образом, что - то вроде этого было бы более надежным: grep -q , /sys/devices/system/cpu/cpu*/topology/thread_siblings_list. Впрочем, просто grep 1 /sys/devices/system/cpu/smt/active -qеще ближе к делу - ср. Ответ Оскара
maxschlepzig

1

Самый простой способ проверить, активен ли SMT (общий для HT, который является только фирменным знаком Intel), просто сделайте:

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

дает 0 для неактивных или 1 для активных

Вы можете включить или выключить его во время выполнения с помощью:

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

Catting /sys/devices/system/cpu/smt/controlэто также возможно и выходы on|off|forceoff|notsupported|notimplemented.
maxschlepzig

0

Лучше вы проверите lscpu, где вы можете увидеть «Thread (s) per core: 1», означает только один поток на 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

Стефания уже упоминала lscpu. Я хотел бы добавить немного больше к этому.

На моем процессоре AMD Epyc при наличии автономного логического ядра lscpuотображается новая дополнительная строка под названиемOff-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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.