Отключить гиперпоточность из Linux (нет доступа к BIOS)


26

У меня есть система, запускающая приложение для финансовой торговли на удаленном объекте. У меня нет доступа к МОТ / DRAC, но мне нужно отключить гиперпоточность. Система работает на шестиъядерных процессорах Intel Westmere 3,33 ГГц X5680. Я могу перезагрузиться, но хочу убедиться, что система не поддерживает гиперпоточность из-за проблем с производительностью. Есть ли чистый способ сделать это изнутри Linux?

Редактировать: nohtдиректива, добавленная в командную строку загрузки ядра, не работает. То же самое для RHEL.

Смотрите: https://bugzilla.redhat.com/show_bug.cgi?id=440321#c9.

Ответы:


21

Вы можете сделать это во время выполнения, если хотите. Я нашел хорошее решение, описанное здесь: http://www.absolutelytech.com/2011/08/01/how-to-disable-cpu-cores-in-linux/

Шаг 1: Определите процессоры Linux, которые вы хотите отключить:

cat /proc/cpuinfo

Ищите процессоры, которые имеют одинаковый «идентификатор ядра», вы хотите отключить одну из каждой пары.

Шаг 2: Отключить процессоры с гиперпоточностью (в моем случае последние четыре из 8 «процессоров», которые видел Linux)

echo 0 > /sys/devices/system/cpu/cpu4/online
echo 0 > /sys/devices/system/cpu/cpu5/online
echo 0 > /sys/devices/system/cpu/cpu6/online
echo 0 > /sys/devices/system/cpu/cpu7/online

Вы можете настроить скрипт, который вы запускаете сразу после запуска системы.


1
Это работает почти так, как я ожидал. виртуальные ядра отключены, теперь, когда я выполняю один процессорный поток, он загружает физическое ядро ​​на 100%. Но использование sysbench --num-threads=1 --test=cpu runс разными num-потоками и включенным и выключенным HT говорит о том, что отключение HT снижает производительность, когда есть много потоков, и даже если есть только один поток, нет смысла отключать HT. Поэтому я предлагаю оставить все как есть: это оптимально.
Сергей Павлович ака лазурь

Знаете ли вы, что это за команда, чтобы включить их обратно? Ссылка в начале вашего ответа мертва ~. Благодарность!
user189035 30.10.16

@ user189035: echo 1вместо того, echo 0чтобы включить их снова.
Питер Кордес

@ SergeyP.akaazure, я думаю, что для приложения, предоставляющего финансовые услуги, основной причиной отключения HT является не производительность, а безопасность.
Саймон Рихтер

@SimonRichter В то время, когда этот вопрос был изначально написан, это было действительно исполнение. SMT / HT был не так хорош в некоторых нагрузках на процессоры той эпохи. Разрушение / Призрак и недавние атаки предвестников произошли несколько лет спустя.
Майкл Хэмптон

14

Скрипт для отключения гиперпоточности при запуске машины ...

Чтобы отключить гиперпоточность, я включаю скрипт на машине /etc/rc.local. Он не совсем чистый, но простой в установке, независимый от архитектуры процессора и должен работать на любом современном дистрибутиве Linux.

nano /etc/rc.local

    # place this near the end before the "exit 0"

    for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
        CPUID=$(basename $CPU)
        echo "CPU: $CPUID";
        if test -e $CPU/online; then
                echo "1" > $CPU/online; 
        fi;
        COREID="$(cat $CPU/topology/core_id)";
        eval "COREENABLE=\"\${core${COREID}enable}\"";
        if ${COREENABLE:-true}; then        
                echo "${CPU} core=${CORE} -> enable"
                eval "core${COREID}enable='false'";
        else
                echo "$CPU core=${CORE} -> disable"; 
                echo "0" > "$CPU/online"; 
        fi; 
    done;    

Как это работает?

Информация о ядре Linux и элементы управления доступны в виде файлов в каталоге / sys в современных дистрибутивах Linux. Например:

/ sys / devices / system / cpu / cpu3 содержит информацию о ядре и элементы управления для логического процессора 3.

cat / sys / devices / system / cpu / cpu3 / topology / core_id покажет номер ядра, которому принадлежит этот логический процессор.

echo "0"> / sys / devices / system / cpu / cpu3 / online позволяет отключить логический процессор 3.

Почему это работает?

Я не знаю точно, почему ... но система стала более отзывчивой с отключенной гиперпоточностью (на моем ноутбуке i5 и массивных серверах Xeon с более чем 60 ядрами). Я предполагаю, что это связано с кэшем для каждого процессора, выделением памяти для каждого процессора, выделением планировщика процессора и сложными итерациями приоритетов процесса. Я думаю, что преимущества гиперпоточности перевешивают сложность создания планировщиков ЦП, которые знают, как их использовать.

Для меня проблема с гиперпоточностью такова: если я запущу столько потоков с интенсивным использованием процессора, сколько у меня логических ядер, у меня будут быстрые переключатели контекста для задач с интенсивным использованием процессора, но дорогие для фоновых задач, поскольку гиперпоточность полностью используется интенсивные задачи процессора. С другой стороны, если я запускаю столько потоков с интенсивным использованием процессора, сколько у меня физических ядер, у меня не будет переключений контекста на эти задачи и быстрых переключений контекста для фоновых задач. Вроде бы хорошо, но фоновые задачи найдут свободные логические процессоры и будут работать почти сразу. Как будто они в реальном времени (неплохо -20).

В первом сценарии гиперпоточность - это пустяки, фоновые задачи будут использовать дорогие переключатели контекста, потому что я увеличил гиперпоточность при обычной обработке. Второе недопустимо, поскольку до 50% мощности моего процессора отдается приоритет фоновым задачам.

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

Кроме того, это догадки.

У меня такое впечатление, что лучше, но может и нет.


Я думаю, что мой скриптлет немного легче следовать.
Павел М

9

Для действительно старых ядер (Linux 2.6.9 или около того) добавьте параметр noht к ядру при загрузке.

Эта опция командной строки ядра была удалена, по крайней мере, с Linux 2.6.18 .


С http://www.faqs.org/docs/Linux-HOWTO/BootPrompt-HOWTO.html :

The `noht' Argument

This will disable hyper-threading on intel processors that have this feature. 

Если вы используете lilo, отредактируйте ваш файл /etc/lilo.conf (и запустите lilo впоследствии) или, если вы используете grub, отредактируйте ваш файл /boot/grub/menu.lst.


Это функционально эквивалентно отключению HT в BIOS?
ewwhite

Я не знаю это точно, но да, я бы ожидал, что ничто не будет равнозначно отключению его в BIOS.
Ремс

2
Это система Gentoo. Я попробовал nohtзапись в командной строке ядра grub. Система не выполнила nohtкоманду. То же самое для RHEL. См: bugzilla.redhat.com/show_bug.cgi?id=440321#c9
ewwhite

1
Это устарело, так как по крайней мере Linux 2.6.18 . Опция nohtядра была удалена. Это прискорбно, потому что Linux разрешает обход некоторых ошибок счетчика перфектов Haswell (BJ122, BV98, HSD29) только в том случае, если HT включен , и это происходит еще до загрузки initramfs.
Питер Кордес

9

Вы можете использовать «thread_siblings_list» для каждого ядра, чтобы отключить второе ядро ​​в паре HT.

Следующий командный конвейер является хакерским, не оптимизированным и сделан таким образом, чтобы облегчить понимание.

cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | \
awk -F, '{print $2}' | \
sort -n | \
uniq | \
( while read X ; do echo $X ; echo 0 > /sys/devices/system/cpu/cpu$X/online ; done )

Итак, возьмите все списки дочерних элементов потока, извлеките второй ЦП для каждой пары, получите уникальный список и затем отключите их.

Имеет ли это смысл?

если я выполнил команду «cat / proc / cpuinfo» после запуска выше, число ядер уменьшается вдвое.


Это отличный ответ. Мне пришлось изменить его следующим образом, чтобы работать в моих целях: echo 0 > /sys/devices/system/cpu/cpu$X/onlineстановитсяecho 0 | sudo tee /sys/devices/system/cpu/cpu$X/online
карбокатион

5

Более новые ядра обеспечивают управление одновременной многопоточностью (SMT).

Вы можете проверить состояние SMT с помощью;

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

Изменить состояние с помощью

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

Варианты есть;

  • на
  • от
  • forceoff

Мы проверили это с Linux Kernel 4.4.0


Привет Ник и добро пожаловать на сайт. Информация о тестах (и версиях) весьма ценна.
Кубанчик

Отлично, протестировано на Ubuntu 16.04.6 LTS
Старейшина Гик

4

Ответ Лукаса хорош, но на самом деле не работает для отключения HT, потому что идентификатор ядра не может служить для идентификации братьев и сестер HT. Этот скрипт работает вместо:

#!/bin/bash
for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
    CPUID=`basename $CPU | cut -b4-`
    echo -en "CPU: $CPUID\t"
    [ -e $CPU/online ] && echo "1" > $CPU/online
    THREAD1=`cat $CPU/topology/thread_siblings_list | cut -f1 -d,`
    if [ $CPUID = $THREAD1 ]; then
        echo "-> enable"
        [ -e $CPU/online ] && echo "1" > $CPU/online
    else
        echo "-> disable"
        echo "0" > $CPU/online
    fi
done

твой сценарий - мой вариант. мы должны проверить, что произойдет, если у вас несколько процессоров, просто чтобы быть уверенным.
Paul M

@PaulM Это именно то место, где я протестировал и использовал его для своих целей: система Haswell с 2 сокетами.
Антон

0

Мне пришлось ждать, пока я не смогу попасть в МОТ / Драк. Параметры загрузки ядра не работают в текущих дистрибутивах Linux.


0

В пакете libsmbios-bin (Debian, Ubuntu и т. Д.) У вас есть двоичные файлы isCmosTokenActive и activCmosToken. Вместе со списком токенов вы можете попробовать что-то вроде этого:

# isCmosTokenActive 0x00d1 # CPU_Hyperthreading_Enable
[...] Type 0x00d1  Location 0x46 AND(fe) OR(0)  BITFIELD: 1
# isCmosTokenActive 0x00d2 # CPU_Hyperthreading_Disable
[....] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 0

Затем активируйте токен CPU_Hyperthreading_Disable:

# activateCmosToken 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 1

Убедитесь, что:

# isCmosTokenActive 0x00d1 # CPU_Hyperthreading_Enable
[...] Type 0x00d1  Location 0x46 AND(fe) OR(0)  BITFIELD: 0
# isCmosTokenActive 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 1

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


0

Основываясь на информации, предоставленной Полом М здесь, я бы «написал» это так:

fgrep , /sys/devices/system/cpu/cpu*/topology/thread_siblings_list |
cut -d, -f2 | sort -u |
sudo xargs -rI, sh -c 'echo 0 > /sys/devices/system/cpu/cpu,/online'

Конечно, он не отключает гиперпоточность в том же смысле, что и при работе с BIOS , в основном он говорит только планировщику задач ядра не использовать некоторые ядра, потому что мы знаем, что они фальшивые.

Программное обеспечение, которое сделало предположение на основе предыдущего состояния /procили /sysподсистемы, все еще может работать неоптимально или даже не работать из-за этого изменения времени выполнения, поэтому может потребоваться его перезапуск. Например, я заметил, irqbalanceчто в таких обстоятельствах был склонен к провалу.


0

Отключить HT:

echo 0 |sudo tee /sys/devices/system/cpu/cpu{4..7}/online

Включить HT:

echo 1 |sudo tee /sys/devices/system/cpu/cpu{4..7}/online

Примечание. Это на самом деле не отключает HyperThreading, но отключает «поддельные» ядра, получая почти тот же результат.


Мне нравится, как вы используете tee, но это все еще не дает реального ответа на вопрос. Эти команды применяются только к определенным аппаратным конфигурациям и могут иметь непреднамеренные последствия для других аппаратных конфигураций. И объяснение того, что делают эти команды, полностью отсутствует.
Касперд

Так как 0 означает «выключено», а 1 означает «включено», я подумал, что было легко понять, что первое отключает 4 ядра (из фальшивых 8 на кандокоре с включенной гиперпоточностью), а второе снова включает их ... Если у вас ДВОЙНОЙ основное число должно быть {3,4} вместо {4..7}. Если вы используете октакор, это должно быть {8..15}
Zibri

0

Старая тема, но была причина попробовать этот эксперимент. Во-первых, я вовсе не уверен, что отключение (слегка фальшивых) процессоров во время выполнения действительно эквивалентно отключению Hyperthreading при загрузке. Тем не менее, я увидел небольшое повышение производительности в нашем приложении. (Но недостаточно, чтобы сохранить.)

Использовал значение thread_siblings (общее для многопоточных процессоров) в качестве ключа для включения / выключения:

for i in /sys/devices/system/cpu/cpu[0-9]* 
do echo "$(cat $i/topology/thread_siblings) $i" 
done | 
awk '{v = (a[$1] ? 0 : 1); a[$1] = 1; print "echo " v " > " $2 "/online"}' | 
sudo sh 

Попробуйте команду без окончательного sudo sh, чтобы проверить правильность.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.