Wyłącz hiperwątkowość w Ubuntu

15

Korzystam z serwera Ubuntu 16.04. Widzę, że wątki hype są włączone, gdy korzystam z polecenia lscpu.

Chcę to wyłączyć. Przeszedłem fora Ubuntu i tu i tutaj .

To są dobre dyskusje, dlaczego hiperwątkowanie może nie być dobre. Ale nie ma ostatecznego rozwiązania, jak to wyłączyć.

Czy ktoś może podać kroki umożliwiające wyłączenie hiperwątkowania? Dzięki .

Jan
źródło
3
Czy próbowałeś wyłączyć go w systemie BIOS?
edwinksl,
tak, nie mogłem znaleźć opcji dla HT
Jan

Odpowiedzi:

9

Wprowadzenie

To interesujące pytanie. Prawdopodobnie jeden z najciekawszych od miesięcy dla mnie osobiście. Podobnie jak OP, nie ma opcji wyłączenia Hyper Threading w moim starym BIOS-ie (wynaleziony w 2012 r., Zaktualizowany w 2016 r. Lub mniej więcej).

Błędy hiperwątkowości w Intel Skylake i Kaby Lake:

Każdy, kto korzysta z procesorów Intel Skylake lub Kaby Lake , musi przeczytać raporty o błędach dotyczące Hyper Threading, które pojawiły się kilka miesięcy temu. Ta historia z rejestru brytyjskiego wyjaśnia, w jaki sposób deweloperzy Debiana zauważyli, jak Hyper Threading może spowodować awarię i uszkodzenie maszyny.

Istnieje wiele problemów ze Skylake zgłoszonych w Ask Ubuntu w ciągu ostatniego roku i zastanawia się, jak rozpoznać, które problemy mogły być spowodowane błędami Hyper Threading.

Ta odpowiedź jest podzielona na trzy części:

  • Wyświetlanie procesorów, gdy Hyper-Threading jest wyłączony / włączony
  • Skrypt Bash do automatyzacji wyłączania / włączania hiperwątkowości
  • Conky ulega awarii, jeśli Hyper Threading jest wyłączony przed rozpoczęciem

Wyświetlanie procesorów, gdy Hyper-Threading jest wyłączony / włączony

Poniżej widać wykorzystanie procesora, gdy hiperwątkowanie jest wyłączone i wykonywany jest test obciążenia procesora. Około 10 sekund później ten sam skrypt jest powtarzany przy włączonym hiperwątkowości. Wreszcie 10 sekund po uruchomieniu skryptu przy wyłączonym hiperwątkowości:

Ustaw opcję Hyper Threading

Wyświetlacz jest podzielony na dwie sekcje:

  • W lewej połowie okna terminala wywołuje skrypt set-hyper-threadingz parametrem 0 (wyłączony), a następnie 1 (włączony).
  • Po prawej stronie conkywyświetla procent wykorzystania procesora przez CPUS od 1 do 8.

Pierwszy skrypt wyłącza Hyper Threading

Przy pierwszym uruchomieniu skryptu Procesory 2, 4, 6 i 8 (według Conky) są zamrożone na 3%, 2%, 2% i 2%. Liczby procesora 1, 3, 5 i 7 zwiększają się do 100% podczas testu warunków skrajnych.

Topologia procesora jest wyświetlana z wyłączonym hiperwątkowością i zgłaszane są tylko cztery rdzenie:

/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

Drugi skrypt włącza Hyper Threading

Przy drugim uruchomieniu skryptu funkcja Hyper-Threading jest włączona, a wszystkie liczby procesorów 1-8 zwiększają się do 100% podczas testu warunków skrajnych.

Topologia procesora jest wyświetlana z włączonym hiperwątkowością i zgłaszane są tylko cztery rdzenie plus i cztery rdzenie wirtualne:

/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

Trzeci skrypt uruchamia Hyper Threading

Zwróć uwagę, jak po zakończeniu drugiego skryptu procesory 2, 4, 6 i 8 pracują na biegu jałowym przy 4%, 2%, 3%, 4%. Jest to ważne, ponieważ w trzecim teście wyłączenie funkcji Hyper-Threading pokazuje te procenty zamrożone przy 4%, 2%, 3%, 4% zamiast 3%, 2%, 2% i 2% od pierwszego testu.

Dlatego wyłączenie hiperwątkowości wydaje się po prostu zamrażać procesory wirtualne w bieżącym stanie.

Pamiętaj również, bez względu na to, czy włączysz lub wyłączysz Hyper-Threading, skrypt nadal wyświetla „Obsługiwane Hyper-Threading”.


Skrypt Bash do automatyzacji wyłączania / włączania hiperwątkowości

Przeglądając poniższy skrypt pamiętaj, że Conky numeruje procesory od 1 do 8, ale Linux numeruje procesory od 0 do 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

UWAGA: Program stressjest wbudowany we wszystkie systemy Debian, których Ubuntu jest pochodną. Dlatego nie musisz pobierać ani instalować żadnych pakietów, aby uruchomić ten skrypt w Ubuntu.

Jeśli masz dwurdzeniowy procesor, musisz usunąć (lub skomentować #) linie kontrolujące procesor o numerach 5 i 7.

Podziękowania dla Hi-Angel za linię bashową grep "" /sys/devices/system/cpu/cpu*/topology/core_idwyświetlającą topologię procesora.


Conky ulega awarii, jeśli Hyper Threading jest wyłączony przed rozpoczęciem

Aby maksymalnie wykorzystać procesory 2, 4, 6, 8, próbowałem wyłączyć Hyper-Threading podczas uruchamiania. Użyłem tego skryptu, aby to zrobić:

# 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

Jednak conkyulega awarii z błędem segmentacji, jeśli hiperwątkowanie jest wyłączone podczas uruchamiania. Jako taki musiałem skomentować cztery @rebootlinie w skrypcie.

Conky Code do wyświetlania procentu wykorzystania procesora i współczynnika obciążenia

Jeśli chcesz skonfigurować podobny ekran w Conky, oto odpowiedni fragment kodu:

${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}

UWAGA: Powyższy kod Nvidia nigdy nie był testowany, ponieważ nie mam jeszcze procesora graficznego Nvidia działającego pod Ubuntu. Już niedługo rok :)

WinEunuuchs2Unix
źródło
1
Przepraszamy, ale nohtnie istnieje. Nawet poznałem tę opcję za pośrednictwem źródeł linux-4.13-rc1, które czasami mam. Jednak na pewno rozumiem, co mogło cię pomylić: raport o błędach danych skarży się, że opcja nie działa, a następnie jest zamykana nextrelease, jakby coś naprawili. Jeśli jednak przeczytasz komentarze, zobaczysz, że jedynym zastosowaniem nohtjest ręcznie spreparowany skrypt, który sprawdza linię poleceń jądra pod kątem opcji, a następnie wyłącza rdzenie przez /sys/system plików. IOW nohtjest bezużyteczne.
Cześć Anioł
@ Cześć Anioł Dziękuję za zwrócenie uwagi, że nie jest to konieczne. Testowałem bez niego, a rdzenie off-line podwoiły się z 2,2,5,5% (bez noht) do 5,5,10,10% (bez noht). Zrobię dziś więcej testów. Przeszukałem dokumentację parametrów jądra i nie mogłem znaleźć żadnego odniesienia do noht.
WinEunuuchs2Unix
Na marginesie, nie ma języka maszynowego / ludzkiego do indeksowania :) Aby rozwiązać problem pomyłek z indeksami zaczynającymi się od 0, 1, a nawet z określoną liczbą (jak to jest w MiniZinc) , lepiej myśleć w kategoriach zestawów indeksów , tj. obrzucenie z zestawu indeksów do innego zestawu. Wyodrębnienie go pozwala łatwiej zauważyć, że niektóre istotne elementy danych, które nie reprezentują indeksów, mogą faktycznie zostać użyte do indeksowania po tym, jak nieco się pokręciły. Zaletą jest myślenie o koncepcji niezwiązanej z układem pamięci i innymi ograniczeniami.
Cześć Angel
@ Hi-Angel Chyba podobne porównanie między „pozycją początkową” a „odsunięciem”. W każdym razie zamierzam przepisać tę odpowiedź na podstawie ostatnich dwóch dni testowania i kodowania, aby nasze komentarze wkrótce
stały
6

Najnowsze jądra obsługują parametr jądra maxcpus .

Pozwala to ustawić liczbę procesorów na liczbę fizycznych rdzeni. Może to być pomocne w ograniczaniu zagrożeń powodowanych przez luki MDS w procesorach Intel z rodziny 6.

W jaki sposób:

z uprawnieniami sudo (root) otwórz / etc / default / grub w swoim ulubionym edytorze tekstu.

Znajdź linię zaczynającą się od GRUB_CMDLINE_LINUX_DEFAULT =

i dodaj maxcpus = n do dowolnych istniejących parametrów jądra, takich jak wspólne parametry cichego powielania (gdzie n = liczba rdzeni fizycznych twojego procesora.

Na przykład na moim zaufanym dwurdzeniowym procesorze Intel (R) Core (TM) i3-3220 @ 3,30 GHz z dodanym hyperthreadingiem dodałem maxcpus = 2, aby wyłączyć hyperthreading podczas uruchamiania.

Zapisz plik, a następnie wydaj polecenie sudo update-grubi uruchom ponownie.

Możesz potwierdzić sukces, wydając polecenie, lscpu | grep "per core"które powinno dostarczyć dane wyjściowe w następujący sposób:

Thread(s) per core: 1

Testowane na jądrze 4.4.0

Źródła:

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

Starszy Geek
źródło
1
Ciekawe linki Dzięki za udostępnienie.
WinEunuuchs2Unix
@ WinEunuuchs2Unix Cała przyjemność po mojej stronie. Zawsze chętny do pomocy!
Starszy Geek
5

Możesz wyłączyć hyperthreading w Linuksie jako root lub z uprawnieniami administratora w:

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

Możesz wyświetlić bieżący stan hiperwątkowania za pomocą:

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

To polecenie wypisuje jeden z:

on|off|forceoff|notsupported|notimplemented

Alternatywnie, większość oprogramowania układowego BIOS-u zawiera również opcję wyłączania hipertekstu. Jeśli jest wyłączony w systemie BIOS, powyższy kot prawdopodobnie powraca forceoff.

maxschlepzig
źródło
Czy próbowałeś tego, aby wyłączyć hiperwątkowość przy rozruchu?
Elder Geek
1
@ElderGeek nie, nie próbowałem maxcpus=parametru jądra do wyłączania hyperthreading. Głównie dlatego, że nie mogę znaleźć żadnej oficjalnej dokumentacji dotyczącej jej interakcji z rdzeniami hiperwątkowości. Czy na pewno zawsze wyłączasz hiperwątkowanie, jeśli określisz maxcpus=#real_cores? A może skończysz z połową prawdziwych rdzeni z HT włączoną w niektórych systemach? Również jedno maxcpus=ustawienie nie jest przenośne między maszynami o różnej liczbie rdzeni. Utrzymywanie zmian tego parametru dla różnych maszyn byłoby uciążliwe i podatne na błędy.
maxschlepzig
Z mojego doświadczenia wynika, że ​​zawsze wyłączałem hyperthreading, jeśli podasz maxcpus = # real_cores, oczywiście pod warunkiem, że ufasz lscpu | grep "per core"wynikowi. Podkreślasz przenośność, jednak z drugiej strony ustawienie parametru jądra raz nie wydaje się zbyt uciążliwym zadaniem. Dla mnie.
Elder Geek
2

Oto skrypt do identyfikacji rdzeni ht i przełączania ich w trybie online / offline.

#!/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 , może możesz dodać to do swojej doskonałej odpowiedzi.

visit1985
źródło
Musiałem posortować listę numerycznie, aby działała poprawnie:for i in $(find /sys/devices/system/cpu/cpu[0-9]* -maxdepth 0 -type d |sort -V); do
neuhaus
2

maxcpus=nParametr GRUB_CMDLINE_LINUX_DEFAULT=nie działa prawidłowo. Zostało mi 2 rdzenie i 4 wątki zamiast 4 rdzeni 4 wątków.

Znalazłem rozwiązanie.

Dodaj mitigations=auto,nosmtdo GRUB_CMDLINE_LINUX_DEFAULT=zamiast

Testowany na Ubuntu 16.04 LTS z systemem Linux 4.4.0.

Źródło: https://wiki.ubuntu.com/SecurityTeam/KnowledgeBase/MDS

MobTactics
źródło
1

Nieco bardziej niezawodny sposób szukania w jądrze par hiperwątków jest potrzebny w systemach, w których na płycie głównej znajduje się wiele gniazd procesora, ponieważ core_id jest zduplikowany. Oto moja wersja na systemie z dwoma 8-rdzeniowymi układami Xeon (przykład z 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

Do różnych celów możesz także zajrzeć do plików

/sys/devices/system/cpu/present
/sys/devices/system/cpu/online
/sys/devices/system/cpu/offline
4 manekiny
źródło
0

Jeśli czytasz dyskusje, to prawdopodobnie wiesz, że zwykle nie ma sensu wyłączać, więc założę się, że chcesz tego do celów edukacyjnych.

Ideą HT jest posiadanie wielu zestawów rejestrów CPU dla każdego rdzenia fizycznego (tak zwane rdzenie wirtualne) . Nie ma „lepszego” wirtualnego rdzenia, są identyczne. Uzbrojeni w tę wiedzę możesz wyłączyć rdzenie wirtualne, z wyjątkiem jednego dla każdego fizycznego.

Najpierw chcesz wiedzieć, która para wirtualnych rdzeni należy do którego fizycznego rdzenia w /sys/systemie plików. Możesz użyć core_iddo tego pliku:

λ 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

Z danych wyjściowych można wywnioskować, że cpu0 + cpu2 są zawarte w jednym fizycznym rdzeniu, a cpu1 + cpu3 w drugim. Teraz podnieś uprawnienia i użyj echopolecenia, aby wyłączyć jedno z każdej pary:

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

Zauważ, że procesor nie ma pliku „online” i nie można go wyłączyć, dlatego zamiast tego wyłączyłem procesor.

Cześć aniele
źródło
0

Odpowiedź @ visit1985 nie działa, jeśli separator w liście wątków_siblings_list nie jest przecinkiem (na przykład w moim systemie AMD Ryzen).

Oto skrypt wyłączający hiperwątkowanie, który działa z dowolnym separatorem:

#!/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

A oto jeden, aby włączyć hiperwątkowość:

#!/bin/bash

for cpu in /sys/devices/system/cpu/cpu[1-9]*; do
    echo 1 > "$cpu/online"
done
Andreas Abel
źródło
Czy ta metoda działa na twoim procesorze Ryzen?
Elder Geek