Отключить гиперпоточность в Ubuntu


13

Я работаю на сервере Ubuntu 16.04. Я вижу, что Hype Threading включен, когда я использую команду lscpu.

Я хочу отключить это. Я прошел форумы Ubuntu и здесь и здесь .

Это хорошие дискуссии, почему гиперпоточность может не быть хорошей. Но нет окончательного решения о том, как его отключить.

Кто-нибудь может дать инструкции по отключению гиперпоточности? Благодарю .


3
Вы пытались отключить его в BIOS?
edwinksl

да, не могли бы найти вариант для HT
джон

Ответы:


9

Вступление

Это интересный вопрос. Наверное, один из самых интересных за месяцы лично для меня. Как и OP, в моем старом BIOS нет опции отключения Hyper Threading (изобретена в 2012 году, обновлена ​​в 2016 году или около того).

Ошибки Hyper-Threading в Intel Skylake и Kaby Lake:

Любой, кто использует процессоры Intel Skylake или Kaby Lake , должен прочитать отчеты об ошибках в Hyper Threading, которые появились пару месяцев назад. В этой истории о регистрации в Великобритании рассказывается, как разработчики Debian обнаружили, как Hyper Threading может привести к сбою и повреждению компьютера.

За последний год в Ask Ubuntu сообщалось о многочисленных проблемах со Skylake, и возникает вопрос, как определить, какие проблемы могли быть вызваны ошибками Hyper Threading.

Этот ответ делится на три части:

  • Отображение процессоров, когда Hyper-Threading выключен / включен
  • Скрипт Bash для автоматизации включения / выключения гиперпоточности
  • Conky Сбои, если Hyper Threading отключена до его запуска

Отображение процессоров, когда Hyper-Threading выключен / включен

Ниже вы можете увидеть загрузку ЦП, когда гиперпоточность отключена и выполняется нагрузочный тест ЦП. Примерно через 10 секунд тот же сценарий повторяется с включенной гиперпоточностью. Наконец, через 10 секунд скрипт запускается с отключенной гиперпоточностью:

Установить Hyper Threading noht

Дисплей разделен на две части:

  • В левой половине окна терминала вызывается скрипт set-hyper-threadingс параметром 0 (выкл) и затем 1 ( вкл ).
  • В правой половине conkyотображается загрузка ЦП в процентах от 1 до 8.

Первый скрипт запускает Hyper Threading

При первом запуске скрипта номера ЦП 2, 4, 6 и 8 (по словам Конки) заморожены на 3%, 2%, 2% и 2%. Во время стресс-теста номера ЦП 1, 3, 5 и 7 достигают 100%.

Топология ЦП отображается с отключенной гиперпоточностью, и сообщается только о четырех ядрах:

/sys/devices/system/cpu/cpu0/topology/core_id:0
/sys/devices/system/cpu/cpu2/topology/core_id:1
/sys/devices/system/cpu/cpu4/topology/core_id:2
/sys/devices/system/cpu/cpu6/topology/core_id:3

Второй скрипт запускает Hyper Threading

Во второй раз, когда скрипт запускается, Hyper-Threading включается, и все процессорные числа 1-8 увеличиваются до 100% во время стресс-теста.

Топология ЦП отображается с включенной гиперпоточностью и сообщается только о четырех ядрах плюс и четырех виртуальных ядрах:

/sys/devices/system/cpu/cpu0/topology/core_id:0
/sys/devices/system/cpu/cpu1/topology/core_id:0
/sys/devices/system/cpu/cpu2/topology/core_id:1
/sys/devices/system/cpu/cpu3/topology/core_id:1
/sys/devices/system/cpu/cpu4/topology/core_id:2
/sys/devices/system/cpu/cpu5/topology/core_id:2
/sys/devices/system/cpu/cpu6/topology/core_id:3
/sys/devices/system/cpu/cpu7/topology/core_id:3

Третий скрипт запускает Hyper Threading

Обратите внимание, как после завершения второго сценария процессоры 2, 4, 6 и 8 работают на холостом ходу 4%, 2%, 3%, 4%. Это важно, потому что в третьем тесте отключение Hyper-Threading показывает процент загрузки процессора, зафиксированный на уровне 4%, 2%, 3%, 4%, а не 3%, 2%, 2% и 2% от первого теста.

Поэтому отключение гиперпоточности просто останавливает виртуальные процессоры в текущем состоянии.

Также обратите внимание, что независимо от того, включен ли Hyper-Threading или нет, сценарий по-прежнему отображает «Hyper-Threading Supported».


Скрипт Bash для автоматизации включения / выключения гиперпоточности

При просмотре приведенного ниже сценария имейте в виду, что Conky нумерует ЦП от 1 до 8, а Linux нумерует ЦП от 0 до 7.

#!/bin/bash

# NAME: set-hyper-threading
# PATH: /usr/local/bin
# DESC: Turn Hyper threading off or on.

# DATE: Aug. 5, 2017.

# NOTE: Written Part of testing for Ubuntu answer:
#       /ubuntu/942728/disable-hyper-threading-in-ubuntu/942843#942843

# PARM: 1="0" turn off hyper threading, "1" turn it on.

if [[ $# -ne 1 ]]; then
    echo 'One argument required. 0 to turn off hyper-threading or'
    echo '1 to turn hyper-threading back on'
    exit 1
fi

echo $1 > /sys/devices/system/cpu/cpu1/online
echo $1 > /sys/devices/system/cpu/cpu3/online
echo $1 > /sys/devices/system/cpu/cpu5/online
echo $1 > /sys/devices/system/cpu/cpu7/online

grep "" /sys/devices/system/cpu/cpu*/topology/core_id

grep -q '^flags.*[[:space:]]ht[[:space:]]' /proc/cpuinfo && \
    echo "Hyper-threading is supported"

grep -E 'model|stepping' /proc/cpuinfo | sort -u

stress --cpu 8 --io 1 --vm 1 --vm-bytes 128M --timeout 10s

ПРИМЕЧАНИЕ . Программа stressвстроена во все системы Debian, производная от Ubuntu. Поэтому вам не нужно скачивать и устанавливать пакеты для запуска этого скрипта в Ubuntu.

Если у вас двухъядерный процессор, вам нужно удалить (или закомментировать #) строки, управляющие процессорами с номерами 5 и 7.

Благодарим Hi-Angel за grep "" /sys/devices/system/cpu/cpu*/topology/core_idотображение строки топологии процессора.


Conky Сбои, если Hyper Threading отключена до его запуска

Чтобы получить максимально возможную загрузку процессоров 2, 4, 6, 8, я попытался отключить Hyper-Threading во время загрузки. Я использовал этот скрипт для этого:

# NAME: /etc/cron.d/turn-off-hyper-threading
# DATE: Auguust 5, 1017
# DESC: This turns off CPU 1, 3, 5 & 7
# NOTE: Part of testing for Ubuntu answer:
#       /ubuntu/942728/disable-hyper-threading-in-ubuntu/942843#942843
# BUGS: Conky crashes with Segmentation Fault when CPU 2,4,6 & 8 (as conky calls them)
#       are off-line.
#
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# @reboot   root    echo 0 > /sys/devices/system/cpu/cpu1/online
# @reboot   root    echo 0 > /sys/devices/system/cpu/cpu3/online
# @reboot   root    echo 0 > /sys/devices/system/cpu/cpu5/online
# @reboot   root    echo 0 > /sys/devices/system/cpu/cpu7/online

Однако происходит conkyсбой при сегментации, если при запуске гиперпоточность отключена. Таким образом, я должен был закомментировать четыре @rebootстроки в сценарии.

Conky Code для отображения процента использования процессора и коэффициента загрузки

Если вы заинтересованы в настройке подобного дисплея в Conky, вот соответствующий фрагмент кода:

${color orange}${voffset 2}${hr 1}
${color2}${voffset 5}Intel® i-7 3630QM 3.4 GHz: ${color1}@  ${color green}${freq} MHz   
${color}${goto 13}CPU 1 ${goto 81}${color green}${cpu cpu1}% ${goto 131}${color3}${cpubar cpu1 18}
${color}${goto 13}CPU 2 ${goto 81}${color green}${cpu cpu2}% ${goto 131}${color3}${cpubar cpu2 18}
${color}${goto 13}CPU 3 ${goto 81}${color green}${cpu cpu3}% ${goto 131}${color3}${cpubar cpu3 18}
${color}${goto 13}CPU 4 ${goto 81}${color green}${cpu cpu4}% ${goto 131}${color3}${cpubar cpu4 18}
${color}${goto 13}CPU 5 ${goto 81}${color green}${cpu cpu5}% ${goto 131}${color3}${cpubar cpu5 18}
${color}${goto 13}CPU 6 ${goto 81}${color green}${cpu cpu6}% ${goto 131}${color3}${cpubar cpu6 18}
${color}${goto 13}CPU 7 ${goto 81}${color green}${cpu cpu7}% ${goto 131}${color3}${cpubar cpu7 18}
${color}${goto 13}CPU 8 ${goto 81}${color green}${cpu cpu8}% ${goto 131}${color3}${cpubar cpu8 18}
${color1}All CPU ${color green}${cpu}% ${goto 131}${color1}Temp: ${color green}${hwmon 2 temp 1}°C ${goto 250}${color1}Up: ${color green}$uptime
${color green}$running_processes ${color1}running of ${color green}$processes ${color1}loaded processes.
Load Avg. 1-5-15 minutes: ${alignr}${color green}${execpi .001 (awk '{printf "%s/", $1}' /proc/loadavg; grep -c processor /proc/cpuinfo;) | bc -l | cut -c1-4} ${execpi .001 (awk '{printf "%s/", $2}' /proc/loadavg; grep -c processor /proc/cpuinfo;) | bc -l | cut -c1-4} ${execpi .001 (awk '{printf "%s/", $3}' /proc/loadavg; grep -c processor /proc/cpuinfo;) | bc -l | cut -c1-4}
${color1}NVIDIA  ${color}-GPU ${color green}${nvidia gpufreq} Mhz  ${color}-Memory ${color green}${nvidia memfreq} Mhz
${color1}GT650M ${color}-Temp ${color green}${nvidia temp}°C  ${color}-Threshold ${color green}${nvidia threshold}°C
${color orange}${voffset 2}${hr 1}

ПРИМЕЧАНИЕ. Приведенный выше код Nvidia никогда не тестировался, потому что у меня еще нет графического процессора Nvidia, работающего под Ubuntu. Любой год скоро сейчас :)


1
Извините, но nohtне существует. Я даже нашел этот вариант в источниках linux-4.13-rc1, которые иногда случаются. Однако я, конечно, понимаю, что могло вас смущать: отчет об ошибках dat жалуется, что опция не работает, а затем закрывается nextrelease, как будто они что-то исправили. Однако если вы прочтете комментарии, вы увидите, что единственное использование noht- это сценарий, созданный вручную, который проверяет параметр командной строки ядра, а затем отключает ядра через /sys/файловую систему. IOW nohtбесполезен.
Привет, Ангел,

@ Привет-ангел. Спасибо, что указали, что в этом нет необходимости. Я провел тестирование без него, и количество автономных ядер удвоилось с 2,2,5,5% (без noht) до 5,5,10,10% (без noht). Я сделаю больше испытаний сегодня вечером. Я искал документацию по параметрам ядра и не смог найти никакой ссылки на noht.
WinEunuuchs2Unix

Кроме того, нет никакого машинного / человеческого языка для индексации :) Чтобы разрешить путаницу с индексами, начинающимися с 0, 1 или даже с определенным числом (как в MiniZinc) , лучше думать с точки зрения наборов индексов , то есть Выражение из набора показателей в другой набор. Абстрагируясь от этого, вы можете легче заметить, когда некоторые элементы, относящиеся к данным, которые не представляют индексы, могут фактически использоваться для индексации после небольшого переворота. Преимущество заключается в том, что необходимо иметь в виду концепцию, не связанную с макетом памяти и другими ограничениями.
Привет, Ангел,

@ Hi-Angel Аналогичное сравнение между «Начальной позицией» и «Смещением», я думаю. В любом случае, я собираюсь переписать этот ответ, основываясь на последних двух днях тестирования и кодирования, поэтому наши комментарии скоро устареют ...
WinEunuuchs2Unix

6

Последние ядра поддерживают параметр ядра maxcpus .

Это позволяет вам установить количество процессоров на количество физических ядер. Это может быть полезно для смягчения угроз, вызванных уязвимостями MDS на процессорах Intel из семейства 6.

Как:

с привилегиями sudo (root) откройте / etc / default / grub в вашем любимом текстовом редакторе.

Найдите строку, которая начинается с GRUB_CMDLINE_LINUX_DEFAULT =

и добавьте maxcpus = n к любым существующим параметрам ядра, таким как общие параметры тихого всплеска (где n = количество физических ядер, которое имеет ваш процессор.

Например, на моем надежном двухъядерном процессоре Intel (R) Core (TM) i3-3220 с тактовой частотой 3,30 ГГц с гиперпоточностью я добавил maxcpus = 2, чтобы отключить гиперпоточность во время загрузки.

Сохраните файл, затем введите команду sudo update-grubи перезагрузите компьютер.

Вы можете подтвердить успех, введя команду, lscpu | grep "per core"которая должна выдать вывод, подобный этому:

Thread(s) per core: 1

Проверено на ядре 4.4.0

Источники:

https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/kernel-parameters.txt

https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html

/unix/145645/disabling-cpu-cores-on-quad-core-processor-on-linux


1
Интересные ссылки. Спасибо, что поделился.
WinEunuuchs2Unix

@ WinEunuuchs2Unix Мое удовольствие. Всегда готов помочь!
Старейшина Гик

4

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

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

Вы можете отобразить текущий статус гиперпоточности с помощью:

$ cat /sys/devices/system/cpu/smt/control

Эта команда печатает один из:

on|off|forceoff|notsupported|notimplemented

Кроме того, большинство прошивок BIOS также включают опцию отключения гиперпоточности. Если он отключен в BIOS, вышеупомянутый кот, скорее всего, вернется forceoff.


Вы пробовали это, чтобы отключить гиперпоточность при загрузке?
Старейшина Гик

1
@ ElderGeek нет, я не пробовал maxcpus=параметр ядра для отключения гиперпоточности. Главным образом потому, что я не могу найти никакой официальной документации по взаимодействию с ядрами с гиперпоточностью. Гарантируется ли всегда отключать гиперпоточность, если вы укажете maxcpus=#real_cores? Или вы могли бы получить половину реальных ядер с поддержкой HT в некоторых системах? Также одна maxcpus=настройка не переносима между машинами с различным количеством ядер. Ведение вариаций этого параметра для разных машин было бы утомительным и подверженным ошибкам.
maxschlepzig

По моему опыту, это всегда отключало гиперпоточность, если вы указываете maxcpus = # real_cores, конечно, при условии, что вы доверяете выводу. lscpu | grep "per core"Вы ставите точку зрения в отношении переносимости, однако, с другой стороны, установка параметра ядра однажды не кажется слишком обременительной задачей. мне.
Старейшина Гик

2

Вот скрипт для идентификации ht-ядер и переключения их онлайн / оффлайн.

#!/bin/bash
typeset -i core_id
typeset -i sibling_id
typeset -i state

for i in /sys/devices/system/cpu/cpu[0-9]*; do
  core_id="${i##*cpu}"
  sibling_id="-1"

  if [ -f ${i}/topology/thread_siblings_list ]; then
    sibling_id="$(cut -d',' -f1 ${i}/topology/thread_siblings_list)"
  fi

  if [ $core_id -ne $sibling_id ]; then
    state="$(<${i}/online)"
    echo -n "$((1-state))" > "${i}/online"
    echo "switched ${i}/online to $((1-state))"
  fi
done

@ WinEunuuchs2Unix , может быть, вы можете добавить это к вашему отличному ответу.


Я должен был численно отсортировать список, чтобы он работал должным образом:for i in $(find /sys/devices/system/cpu/cpu[0-9]* -maxdepth 0 -type d |sort -V); do
neuhaus

2

maxcpus=nПараметр GRUB_CMDLINE_LINUX_DEFAULT=не работает должным образом. У меня осталось 2 ядра и 4 потока вместо 4 ядер 4 потока.

Я нашел решение.

Добавить mitigations=auto,nosmtк GRUB_CMDLINE_LINUX_DEFAULT=вместо

Протестировано на Ubuntu 16.04 LTS с Linux 4.4.0.

Источник: https://wiki.ubuntu.com/SecurityTeam/KnowledgeBase/MDS


1

Для систем, где на материнской плате размещено несколько сокетов ЦП, требуется несколько более надежный способ поиска в ядре пар гиперзадач, поскольку дублируется core_id. Вот моя версия для системы с двумя 8-ядерными чипами Xeon (пример из Ubuntu 16.04):

$ cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list \
> | sort --unique --numeric-sort
0,16
1,17
2,18
3,19
4,20
5,21
6,22
7,23
8,24
9,25
10,26
11,27
12,28
13,29
14,30
15,31

Для различных целей вы также можете посмотреть в файлах

/sys/devices/system/cpu/present
/sys/devices/system/cpu/online
/sys/devices/system/cpu/offline

0

Если вы читали обсуждения, то, вероятно, знаете, что отключать их обычно нецелесообразно, поэтому я предполагаю, что вы хотите, чтобы они были использованы в учебных целях.

Идея HT состоит в том, чтобы иметь несколько наборов регистров ЦП для каждого физического ядра (так называемые виртуальные ядра) . Нет «лучшего» виртуального ядра, они идентичны. Вооружившись этими знаниями, вы можете отключить виртуальные ядра, кроме одного для каждого физического.

Сначала вы хотите узнать, какая пара виртуальных ядер принадлежит какому физическому ядру в /sys/файловой системе. Вы можете использовать core_idфайл для этого:

λ grep "" /sys/devices/system/cpu/cpu*/topology/core_id
/sys/devices/system/cpu/cpu0/topology/core_id:0
/sys/devices/system/cpu/cpu1/topology/core_id:2
/sys/devices/system/cpu/cpu2/topology/core_id:0
/sys/devices/system/cpu/cpu3/topology/core_id:2

По выводу вы можете сделать вывод, что cpu0 + cpu2 содержатся в одном физическом ядре, а cpu1 + cpu3 - в другом. Теперь увеличьте привилегии и используйте echoкоманду для отключения одного в каждой паре:

λ sudo -s
# echo 0 > /sys/devices/system/cpu/cpu1/online
# echo 0 > /sys/devices/system/cpu/cpu2/online

Обратите внимание, что у cpu0 нет «онлайн» файла и его нельзя отключить, поэтому я отключил cpu2.


0

Ответ @ visit1985 не работает, если разделитель в thread_siblings_list не является запятой (как, например, в моей системе AMD Ryzen).

Вот скрипт для отключения гиперпоточности, который работает с любым разделителем:

#!/bin/bash

for cpu in /sys/devices/system/cpu/cpu[1-9]*; do
    if [ -e "$cpu/topology/thread_siblings_list" ]; then
        sibling=$(awk -F '[^0-9]' '{ print $2 }' $cpu/topology/thread_siblings_list)
        if [ ! -z $sibling ]; then
            echo 0 > "/sys/devices/system/cpu/cpu$sibling/online"
        fi
    fi
done

И вот один, чтобы включить Hyper-Threading:

#!/bin/bash

for cpu in /sys/devices/system/cpu/cpu[1-9]*; do
    echo 1 > "$cpu/online"
done

Имеет ли этот метод работы на вашем Ryzen CPU?
Старейшина Компьютерщик,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.