Nonaktifkan hyperthreading dari dalam Linux (tidak ada akses ke BIOS)

26

Saya memiliki sistem yang menjalankan aplikasi perdagangan finansial di fasilitas terpencil. Saya tidak memiliki akses ke ILO / DRAC, tetapi harus menonaktifkan hyperthreading. Sistem menjalankan Intel Westmere 3.33GHz X5680 CPU hex-core. Saya dapat mem-boot ulang, tetapi ingin memastikan bahwa sistem tersebut tidak mengaktifkan hipertread karena masalah kinerja. Apakah ada cara bersih untuk melakukan ini dari dalam Linux?

Sunting: nohtArahan yang ditambahkan ke baris perintah boot kernel tidak berfungsi. Sama untuk RHEL.

Lihat: https://bugzilla.redhat.com/show_bug.cgi?id=440321#c9

putih
sumber

Jawaban:

21

Anda dapat melakukan ini saat runtime jika mau. Saya menemukan solusi bagus yang dijelaskan di sini: http://www.absolutelytech.com/2011/08/01/how-to-disable-cpu-cores-in-linux/

Langkah 1: Identifikasi CPU linux yang ingin Anda matikan:

cat /proc/cpuinfo

Cari CPU yang memiliki "id inti" yang sama, Anda ingin mematikan satu dari setiap pasangan.

Langkah 2: Matikan CPU hyphreading (dalam kasus saya empat terakhir dari total 8 "CPU" dilihat oleh 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

Anda dapat mengatur sendiri skrip yang Anda jalankan sesaat setelah sistem dimulai.

ahus1
sumber
1
Ini bekerja hampir seperti yang saya harapkan. core virtual dinonaktifkan, sekarang ketika saya menjalankan satu thread yang memakan CPU, ia memuat inti fisik sebesar 100%. Tetapi menggunakan sysbench --num-threads=1 --test=cpu rundengan berbagai num-uts dan HT dihidupkan dan dimatikan mengatakan bahwa menonaktifkan HT mengurangi kinerja ketika ada banyak utas, dan bahkan jika hanya ada satu utas, tidak ada manfaat dari mematikan HT. Jadi saya sarankan untuk membiarkannya apa adanya: itu optimal.
Sergey P. alias azure
Apakah Anda tahu apa perintah untuk mengaktifkannya kembali? Tautan di awal jawaban Anda sudah mati ~. Terima kasih!
user189035
@ user189035: echo 1alih-alih echo 0harus mengaktifkannya kembali.
Peter Cordes
@ SergeyP.akaazure, saya pikir untuk aplikasi layanan keuangan, alasan utama untuk mematikan HT bukan kinerja, tetapi keamanan.
Simon Richter
@SimonRichter Pada saat pertanyaan ini awalnya ditulis, itu memang kinerja. SMT / HT tidak sebagus beberapa beban kerja pada CPU pada zaman itu. Hal Meltdown / Spectre, dan serangan Foreshadow yang lebih baru, terjadi bertahun-tahun kemudian.
Michael Hampton
14

Sebuah skrip untuk menonaktifkan hyperthreading di permulaan mesin ...

Untuk menonaktifkan hyperthreading saya memasukkan skrip pada mesin /etc/rc.local. Ini tidak benar-benar bersih, tetapi mudah untuk menginstal, independen dari arsitektur cpu dan harus bekerja pada distribusi linux modern.

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;    

Bagaimana ini bekerja?

Informasi dan kontrol kernel Linux dapat diakses sebagai file dalam direktori / sys pada distribusi linux modern. Sebagai contoh:

/ sys / devices / system / cpu / cpu3 berisi informasi kernel dan kontrol untuk cpu logis 3.

cat / sys / devices / system / cpu / cpu3 / topology / core_id akan menunjukkan nomor inti dari cpu logis ini.

echo "0"> / sys / devices / system / cpu / cpu3 / online memungkinkan untuk menonaktifkan cpu logis 3.

Mengapa ini berhasil?

Saya tidak tahu persis mengapa ... tetapi sistem menjadi lebih responsif dengan hyperthreading off (pada notebook i5 saya dan server Xeon besar dengan 60+ core). Saya kira itu ada hubungannya dengan cache per-cpu, alokasi memori per-cpu, alokasi scheduler cpu dan proses prioritas iterasi kompleks. Saya pikir manfaat dari hyperthreading adalah kelebihan dari kompleksitas membuat penjadwal cpu yang tahu bagaimana menggunakannya.

Bagi saya, masalah dengan hyperthreading adalah: Jika saya memulai thread intensif CPU sebanyak yang saya punya core logis, saya akan memiliki switch konteks cepat untuk tugas intensif CPU, tetapi yang mahal untuk tugas-tugas latar belakang karena hyperthreading benar-benar dikonsumsi oleh tugas intensif cpu. Di sisi lain, jika saya memulai thread intensif CPU sebanyak yang saya punya core fisik saya tidak akan memiliki switch konteks untuk tugas-tugas tersebut dan switch konteks cepat untuk tugas-tugas latar belakang. Tampaknya bagus, tetapi tugas latar belakang akan menemukan prosesor logis gratis dan akan berjalan hampir segera. Sepertinya mereka adalah realtime performace (bagus -20).

Dalam skenario pertama hyperthreading adalah uselles, tugas latar belakang akan menggunakan sakelar konteks mahal karena saya memaksimalkan hyperthreading dengan pemrosesan normal. Yang kedua tidak dapat diterima karena hingga 50% daya cpu saya diprioritaskan ke tugas latar belakang.

Tugas "intensif-cpu" yang saya bicarakan adalah server data mining dan otorisasi kecerdasan buatan (pekerjaan saya). Render blender di komputer dan cluster murah (untuk membuat sketsa rumah masa depan saya).

Juga, ini dugaan.

Saya memiliki kesan yang lebih baik, tetapi mungkin tidak.

Lucas
sumber
Saya pikir scriptlet saya sedikit lebih mudah diikuti.
Paul M
9

Untuk kernel yang benar-benar tua (Linux 2.6.9 atau lebih), tambahkan parameter noht ke kernel saat boot.

Opsi baris perintah kernel ini telah dihapus sejak setidaknya Linux 2.6.18 .


Dari 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. 

Jika menggunakan lilo sunting Anda /etc/lilo.conf (dan jalankan lilo sesudahnya) atau jika menggunakan grub kemudian edit /boot/grub/menu.lst Anda.

rem
sumber
Apakah ini secara fungsional setara dengan menonaktifkan HT di BIOS?
ewwhite
Saya tidak tahu pasti, tapi ya, saya harapkan tidak akan sama dengan menonaktifkannya di BIOS.
rem
2
Ini adalah sistem Gentoo. Saya mencoba nohtentri di baris perintah grub kernel. Sistem tidak menghormati nohtperintah. Sama untuk RHEL. Lihat: bugzilla.redhat.com/show_bug.cgi?id=440321#c9
ewwhite
1
Ini sudah usang sejak setidaknya Linux 2.6.18 . The nohtopsi kernel telah dihapus. Ini sangat disayangkan, karena Linux memungkinkan solusi untuk beberapa Haswell perf-counter errata (BJ122, BV98, HSD29) hanya jika HT aktif , dan ini terjadi sebelum initramfs bahkan dimuat.
Peter Cordes
9

Anda dapat menggunakan "thread_siblings_list" untuk setiap inti untuk mematikan inti kedua dalam pasangan HT.

Pipa perintah berikut ini adalah hacky, tidak dioptimalkan, dan dilakukan dengan cara ini semoga untuk membuatnya lebih mudah dimengerti.

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 )

jadi, ambil semua daftar utas saudara kandung, ekstrak CPU kedua untuk setiap pasangan, dapatkan daftar unik, lalu matikan.

Apakah ini masuk akal?

jika saya melakukan "cat / proc / cpuinfo" setelah menjalankan hal di atas, jumlah core menjadi dua.

Paul M.
sumber
Ini jawaban yang bagus. Saya harus memodifikasinya sebagai berikut agar berfungsi untuk tujuan saya: echo 0 > /sys/devices/system/cpu/cpu$X/onlinemenjadiecho 0 | sudo tee /sys/devices/system/cpu/cpu$X/online
carbocation
5

Kernel yang lebih baru menyediakan kontrol Multithreading Simultan (SMT).

Anda dapat memeriksa status SMT dengan;

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

Ubah status dengan

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

Pilihannya adalah;

  • di
  • mati
  • memaksa

Kami telah menguji ini dengan Linux Kernel 4.4.0

Nick Bascombe-Fox
sumber
Hai Nick dan selamat datang di situs ini. Info tentang tes (dan versi) cukup berharga.
kubanczyk
Luar Biasa, Diuji pada Ubuntu 16.04.6 LTS
Penatua Geek
4

Jawaban Lukas bagus tetapi tidak benar-benar berfungsi untuk menonaktifkan HT karena ID inti tidak dapat berfungsi untuk identifikasi saudara HT. Alih-alih, skrip ini berfungsi:

#!/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
Anton
sumber
skrip Anda adalah variasi milik saya. kita harus memeriksa apa yang terjadi jika Anda memiliki banyak CPU, hanya untuk memastikan.
Paul M
@ PaulM Di situlah saya menguji dan menggunakannya untuk keperluan saya: 2 soket sistem Haswell.
Anton
0

Saya harus menunggu sampai saya bisa masuk ke ILO / Drac. Parameter boot kernel tidak berfungsi pada distribusi Linux saat ini.

putih
sumber
0

Dalam paket libsmbios-bin (Debian, Ubuntu, dll), Anda memiliki binari isCmosTokenActive dan mengaktifkanCmosToken. Bersama dengan token list , Anda dapat mencoba sesuatu seperti ini:

# 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

Kemudian aktifkan token CPU_Hyperthreading_Disable:

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

Memeriksa:

# 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

Sekarang, pertanyaan besarnya adalah apakah Anda hanya perlu reboot atau tidak agar ini berlaku, atau jika diperlukan siklus daya penuh. Cobalah dan lihat bagaimana hasilnya!

svenx
sumber
0

Berdasarkan info yang diberikan oleh Paul M di sini, saya akan "menulis" dengan cara ini:

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'

Tentu saja itu tidak mematikan hyper-threading dalam arti yang sama seperti bermain-main dengan BIOS akan dilakukan , pada dasarnya itu hanya memberitahu scheduler tugas kernel untuk tidak menggunakan beberapa core karena kita tahu mereka palsu.

Perangkat lunak yang membuat asumsinya berdasarkan keadaan /procatau /syssub-sistem sebelumnya mungkin masih berjalan secara sub-optimal atau bahkan gagal karena perubahan run-time ini sehingga diperlukan restart-nya. Misalnya, saya perhatikan irqbalancecenderung gagal dalam keadaan itu.

poige
sumber
0

Nonaktifkan HT:

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

Aktifkan HT:

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

Catatan: Ini tidak benar-benar menonaktifkan HyperThreading tetapi mereka menonaktifkan inti "palsu" yang mendapatkan hasil yang hampir sama.

Zibri
sumber
Saya suka cara Anda menggunakan tee, tetapi ini masih gagal memberikan jawaban nyata untuk pertanyaan itu. Perintah-perintah itu hanya berlaku untuk konfigurasi perangkat keras tertentu dan mungkin memiliki efek yang tidak diinginkan pada konfigurasi perangkat keras lainnya. Dan penjelasan tentang apa yang dilakukan perintah-perintah itu sama sekali tidak ada.
kasperd
Karena 0 berarti mati dan 1 berarti menyala, saya pikir mudah untuk memahami bahwa yang pertama mematikan 4 core (dari 8 palsu pada quandocore dengan hyperthreading aktif) dan yang kedua mengaktifkannya kembali ... Jika Anda memiliki DUAL intinya angka tersebut harus {3,4} bukan {4..7} Jika Anda menggunakan octacore, itu harus {8..15}
Zibri
0

Topik lama, tetapi punya alasan untuk mencoba eksperimen ini. Pertama, saya sama sekali tidak yakin bahwa menonaktifkan CPU (sedikit palsu) saat runtime benar-benar setara dengan menonaktifkan Hyperthreading saat boot. Yang mengatakan, saya memang melihat peningkatan kinerja kecil dalam aplikasi kami. (Tapi tidak cukup untuk menjaga.)

Menggunakan nilai thread_siblings (umum untuk CPU hyperthreaded) sebagai kunci untuk mengaktifkan / menonaktifkan:

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 

Coba perintah tanpa sudo sh terakhir untuk memverifikasi benar.

Preston L. Bannister
sumber