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

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

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

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

11 ответов

Решение

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

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

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

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

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

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

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

  • на
  • от
  • forceoff

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

Вы можете сделать это во время выполнения, если хотите. Я нашел хорошее решение, описанное здесь: 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

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

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

Чтобы отключить гиперпоточность, я включаю скрипт на машине /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% мощности моего процессора отдается приоритет фоновым задачам.

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

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

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

Вы можете использовать "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" после запуска выше, число ядер уменьшается вдвое.

Для действительно старых ядер (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.

Отключить SMT / HT во время загрузки с помощью параметра командной строки ядра nosmt:

        nosmt           [KNL,S390] Disable symmetric multithreading (SMT).
                        Equivalent to smt=1.

                        [KNL,x86] Disable symmetric multithreading (SMT).
                        nosmt=force: Force disable SMT, cannot be undone
                                     via the sysfs control file.

Отключить SMT / HT во время выполнения с помощью управления SMT:

   /sys/devices/system/cpu/smt/control:

     This file allows to read out the SMT control state and provides the
     ability to disable or (re)enable SMT. The possible states are:

        ==============  ===================================================
        on              SMT is supported by the CPU and enabled. All
                        logical CPUs can be onlined and offlined without
                        restrictions.

        off             SMT is supported by the CPU and disabled. Only
                        the so called primary SMT threads can be onlined
                        and offlined without restrictions. An attempt to
                        online a non-primary sibling is rejected

        forceoff        Same as 'off' but the state cannot be controlled.
                        Attempts to write to the control file are rejected.

        notsupported    The processor does not support SMT. It's therefore
                        not affected by the SMT implications of L1TF.
                        Attempts to write to the control file are rejected.
        ==============  ===================================================

     The possible states which can be written into this file to control SMT
     state are:

     - on
     - off
     - forceoff

Ответ Лукаса хорош, но на самом деле не работает для отключения 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

Отключить 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, но отключает "поддельные" ядра, получая почти тот же результат.

В пакете 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

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

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

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 был склонен к провалу в этих обстоятельствах.

Старая тема, но была причина попробовать этот эксперимент. Во-первых, я вовсе не уверен, что отключение (слегка фальшивых) процессоров во время выполнения действительно эквивалентно отключению 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, чтобы проверить правильность.

Другие вопросы по тегам