Nonaktifkan hyper threading di Ubuntu


13

Saya menjalankan server ubuntu 16.04. Saya dapat melihat bahwa hype threading diaktifkan ketika saya menggunakan perintah lscpu.

Saya ingin menonaktifkannya. Saya pergi melalui forum ubuntu dan di sini dan di sini .

Ini adalah diskusi yang bagus mengapa hyper threading mungkin tidak baik. Namun tidak ada solusi pasti tentang cara mematikannya.

Adakah yang bisa memberikan langkah-langkah untuk menonaktifkan hyperthreading? Terima kasih.


3
Sudahkah Anda mencoba menonaktifkannya di BIOS?
edwinksl

ya, tidak dapat menemukan opsi untuk HT
john

Jawaban:


9

pengantar

Ini pertanyaan yang menarik. Mungkin salah satu yang paling menarik dalam beberapa bulan bagi saya secara pribadi. Seperti OP, tidak ada opsi untuk menonaktifkan Hyper Threading di BIOS lama saya (ditemukan 2012, diperbarui 2016 atau lebih).

Bug Hyper-Threading di Intel Skylake dan Kaby Lake:

Siapa pun yang menggunakan prosesor Intel Skylake atau Kaby Lake harus membaca laporan bug tentang Hyper Threading yang muncul beberapa bulan lalu. Ini UK Register cerita merinci bagaimana Debian Pengembang melihat bagaimana Hyper Threading dapat crash dan korup mesin.

Ada banyak masalah dengan Skylake yang dilaporkan di Ask Ubuntu selama setahun terakhir dan orang bertanya-tanya bagaimana membedakan masalah yang mungkin disebabkan oleh bug Hyper Threading.

Jawaban ini dibagi menjadi tiga bagian:

  • Tampilan CPU saat Hyper-Threading dimatikan / dihidupkan
  • Bash script untuk secara otomatis mematikan / mematikan hyper-threading
  • Conky Hancur jika Hyper Threading dimatikan sebelum dimulai

Tampilan CPU saat Hyper-Threading dimatikan / dihidupkan

Di bawah ini Anda dapat melihat pemanfaatan CPU ketika hyper-threading dimatikan dan tes stres CPU dilakukan. Sekitar 10 detik kemudian script yang sama diulangi dengan hyper threading dihidupkan. Akhirnya 10 detik setelah itu skrip dijalankan dengan hyper-threading dimatikan lagi:

Setel Hyper Threading noht

Layar dibagi menjadi dua bagian:

  • Di setengah kiri jendela terminal memanggil script set-hyper-threadingdengan parameter 0 (off) dan kemudian 1 (on).
  • Di bagian kanan conkymenampilkan persentase penggunaan CPU dari CPUS 1 hingga 8.

Script pertama menjalankan Hyper Threading off

Pertama kali skrip dijalankan Nomor CPU 2, 4, 6 & 8 (menurut Conky) dibekukan pada 3%, 2%, 2% dan 2%. CPU Angka 1, 3, 5 dan 7 melonjak hingga 100% saat stress test dijalankan.

Topologi CPU ditampilkan dengan hyper-threading dimatikan dan hanya empat core yang dilaporkan:

/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

Script kedua jalankan Hyper Threading

Kedua kalinya skrip dijalankan Hyper-Threading dihidupkan dan semua CPU Number 1-8 melonjak hingga 100% saat stress test dijalankan.

Topologi CPU ditampilkan dengan hiper-threading dihidupkan dan hanya empat core plus dan empat core virtual yang dilaporkan:

/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

Script ketiga menjalankan Hyper Threading off

Perhatikan bagaimana setelah skrip kedua berakhir, CPU 2, 4, 6 dan 8 idle pada 4%, 2%, 3%, 4%. Ini penting karena dalam tes ketiga mematikan Hyper-Threading off menunjukkan persentase CPU yang dibekukan pada 4%, 2%, 3%, 4% daripada 3%, 2%, 2% dan 2% dari tes pertama.

Karena itu mematikan hyper-threading tampaknya hanya membekukan CPU virtual pada kondisi saat ini.

Perhatikan juga, tidak peduli apakah Anda menghidupkan atau mematikan Hyper-Threading, skrip tetap menampilkan "Hyper Threading Didukung".


Bash script untuk secara otomatis mematikan / mematikan hyper-threading

Saat melihat skrip di bawah ini perlu diingat bahwa Conky memberi nomor CPU dari 1 hingga 8 tetapi Linux memberi nomor CPU dari 0 hingga 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

CATATAN: Program stressini dibangun di semua sistem Debian yang merupakan turunan dari Ubuntu. Karenanya Anda tidak perlu mengunduh dan menginstal paket apa pun untuk menjalankan skrip ini di Ubuntu.

Jika Anda memiliki CPU dual core, Anda perlu menghapus (atau berkomentar dengan #) garis-garis yang mengontrol nomor CPU 5 dan 7.

Kredit ke Hi-Angel untuk bash line yang grep "" /sys/devices/system/cpu/cpu*/topology/core_idmenampilkan topologi CPU.


Conky Hancur jika Hyper Threading dimatikan sebelum dimulai

Untuk mendapatkan CPU 2, 4, 6, 8 hingga pemanfaatan seminimal mungkin, saya mencoba mematikan Hyper-Threading saat boot up. Saya menggunakan skrip ini untuk melakukan itu:

# 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

Namun conkycrash dengan kesalahan segmentasi jika hyper-threading dimatikan saat dijalankan. Karena itu saya harus mengomentari empat @rebootbaris dalam naskah.

Conky Code untuk menampilkan utilisasi persen CPU dan load factor

Jika Anda tertarik untuk menyiapkan tampilan serupa di Conky di sini adalah cuplikan kode yang relevan:

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

CATATAN: Kode Nvidia di atas belum pernah diuji karena saya belum mendapatkan GPU Nvidia yang berfungsi di bawah Ubuntu. Setahun lagi sekarang :)


1
Maaf, tetapi nohttidak ada. Saya bahkan mengambil opsi melalui sumber linux-4.13-rc1 yang kadang-kadang saya miliki. Namun saya tentu mengerti apa yang bisa membingungkan Anda: dat bugreport mengeluh bahwa opsi tidak berfungsi, dan kemudian ditutup nextrelease, seperti jika mereka memperbaiki sesuatu. Namun jika Anda membaca komentar, Anda akan melihat bahwa satu-satunya penggunaan nohtadalah untuk skrip buatan tangan yang memeriksa opsi perintah kernel untuk opsi, kemudian menonaktifkan inti melalui /sys/sistem file. TKI nohttidak berguna.
Hi-Angel

@ Hai-Malaikat Terima kasih telah menunjukkan itu tidak perlu. Saya melakukan pengujian tanpa itu dan core off-line dua kali lipat dari 2,2,5,5% (dengan noht) menjadi 5,5,10,10% (tanpa noht). Saya akan melakukan lebih banyak pengujian malam ini. Saya mencari dokumentasi parameter kernel dan tidak dapat menemukan referensi noht.
WinEunuuchs2Unix

Di samping catatan, tidak ada Mesin / Bahasa manusia untuk mengindeks :) Untuk menyelesaikan kebingungan dengan indeks mulai dari 0, 1, atau bahkan angka tertentu (seperti dalam MiniZinc) , lebih baik untuk berpikir dalam hal set indeks , yaitu a penolakan dari satu set indeks ke set lain. Mengabstraknya memungkinkan Anda untuk mencatat dengan lebih mudah ketika beberapa hal yang relevan dengan data, yang tidak mewakili indeks, sebenarnya dapat digunakan untuk pengindeksan setelah mendapatkan sedikit bujukan. Keuntungannya berasal dari mengingat konsep yang tidak terikat dari tata letak memori dan keterbatasan lainnya.
Hi-Angel

@ Hi-Angel Perbandingan serupa antara "Mulai Posisi" dan "Offset" kurasa. Pokoknya saya akan menulis ulang jawaban ini berdasarkan dua hari terakhir pengujian dan pengkodean sehingga komentar kami akan segera usang ...
WinEunuuchs2Unix

6

Kernel terbaru mendukung parameter kernel maxcpus .

Ini memungkinkan Anda untuk mengatur jumlah CPU ke jumlah core fisik. Ini mungkin berguna untuk membantu mengurangi ancaman yang disebabkan oleh kerentanan MDS pada CPU Intel dari keluarga 6.

Bagaimana:

dengan hak istimewa sudo (root) terbuka / etc / default / grub dengan editor teks favorit Anda.

Temukan baris yang dimulai dengan GRUB_CMDLINE_LINUX_DEFAULT =

dan tambahkan maxcpus = n ke setiap parameter kernel yang ada seperti parameter splash sepi yang umum (di mana n = jumlah core fisik yang dimiliki cpu Anda.

Sebagai contoh pada Intel (R) Core (TM) i3-3220 CPU terpercaya saya @3,30GHz dual core dengan hyperthreading saya menambahkan maxcpus = 2 untuk mematikan hyperthreading pada saat boot.

Simpan file dan kemudian jalankan perintah sudo update-grubdan reboot.

Anda dapat mengkonfirmasi kesuksesan dengan mengeluarkan perintah lscpu | grep "per core"yang seharusnya memberikan hasil seperti ini:

Thread(s) per core: 1

Diuji pada kernel 4.4.0

Sumber:

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
Tautan menarik. Terima kasih telah berbagi.
WinEunuuchs2Unix

@ WinEunuuchs2Unix Dengan senang hati. Selalu ingin membantu!
Penatua Geek

4

Anda dapat menonaktifkan hyperthreading di Linux sebagai root atau dengan hak superuser dengan:

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

Anda dapat menampilkan status hyperthreading saat ini dengan:

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

Perintah ini mencetak salah satu dari:

on|off|forceoff|notsupported|notimplemented

Atau, sebagian besar firmware BIOS juga menyertakan opsi untuk menonaktifkan hyperthreading. Jika dinonaktifkan di BIOS, kucing di atas kemungkinan akan kembali forceoff.


Sudahkah Anda mencoba ini untuk menonaktifkan hyper threading saat boot?
Penatua Geek

1
@ElderGeek tidak, saya belum mencoba maxcpus=parameter kernel untuk menonaktifkan hyperthreading. Terutama karena saya tidak dapat menemukan dokumentasi resmi tentang interaksinya dengan core hyperthreading. Apakah dijamin untuk selalu menonaktifkan hyperthreading jika Anda tentukan maxcpus=#real_cores? Atau mungkin Anda berakhir dengan setengah core nyata dengan HT masih diaktifkan pada beberapa sistem? Juga satu maxcpus=pengaturan tidak portabel antara mesin dengan jumlah inti yang berbeda. Mempertahankan variasi parameter ini untuk mesin yang berbeda akan membosankan dan rentan kesalahan.
maxschlepzig

Dalam pengalaman saya selalu dinonaktifkan hyperthreading jika Anda menentukan maxcpus = # real_cores yang tentu saja Anda percayai output lscpu | grep "per core"Anda membuat poin vaild mengenai portabilitas namun, di sisi lain pengaturan parameter kernel sekali tidak tampak terlalu berat tugas untuk saya.
Penatua Geek

2

Berikut adalah skrip untuk mengidentifikasi core ht dan mengaktifkannya secara 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 , mungkin Anda dapat menambahkan ini ke jawaban terbaik Anda.


Saya harus mengurutkan daftar untuk membuatnya berfungsi dengan baik:for i in $(find /sys/devices/system/cpu/cpu[0-9]* -maxdepth 0 -type d |sort -V); do
neuhaus

2

The maxcpus=nparameter dalam GRUB_CMDLINE_LINUX_DEFAULT=tidak bekerja dengan benar. Itu meninggalkan saya dengan 2 inti dan 4 utas bukannya 4 inti 4 utas.

Saya menemukan solusinya.

Tambahkan mitigations=auto,nosmtke GRUB_CMDLINE_LINUX_DEFAULT=sebagai gantinya

Diuji pada Ubuntu 16.04 LTS dengan Linux 4.4.0.

Sumber: https://wiki.ubuntu.com/SecurityTeam/KnowledgeBase/MDS


1

Cara yang sedikit lebih kuat dalam mencari kernel untuk pasangan hyperthread diperlukan untuk sistem di mana motherboard memiliki beberapa soket CPU karena core_id diduplikasi. Inilah versi saya pada sistem dengan dua chip Xeon 8-core (contoh dari 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

Untuk berbagai keperluan, Anda mungkin juga ingin mencari di file

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

0

Jika Anda membaca diskusi, maka Anda mungkin tahu bahwa biasanya itu tidak masuk akal untuk dinonaktifkan, jadi saya akan menganggap Anda menginginkannya untuk tujuan belajar.

Gagasan HT adalah memiliki beberapa set register CPU untuk setiap inti fisik (yang disebut core virtual) . Tidak ada inti virtual yang "lebih baik", semuanya identik. Berbekal pengetahuan ini, Anda dapat menonaktifkan inti virtual kecuali satu untuk setiap fisik.

Pertama, Anda ingin tahu pasangan inti virtual mana yang memiliki inti fisik pada /sys/sistem file. Anda dapat menggunakan core_idfile untuk itu:

λ 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

Dari output Anda dapat menyimpulkan bahwa cpu0 + cpu2 terkandung dalam satu inti fisik, dan cpu1 + cpu3 di yang lain. Sekarang tinggikan hak istimewa, dan gunakan echoperintah untuk menonaktifkan satu di setiap pasangan:

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

Perhatikan bahwa cpu0 tidak memiliki file "online" dan tidak dapat dinonaktifkan, jadi saya menonaktifkan cpu2.


0

Jawaban @ visit1985 tidak berfungsi jika separator di thread_siblings_list bukan koma (yang, misalnya, kasing pada sistem AMD Ryzen saya).

Berikut ini skrip untuk menonaktifkan hyper-threading yang berfungsi dengan pemisah apa pun:

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

Dan inilah satu untuk mengaktifkan hyper-threading:

#!/bin/bash

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

Apakah metode ini berfungsi pada CPU Ryzen Anda?
Penatua Geek
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.