ปิดใช้งานไฮเปอร์เธรดจากภายใน Linux (ไม่สามารถเข้าถึง BIOS)


26

ฉันมีระบบที่ใช้แอพพลิเคชั่นการซื้อขายทางการเงินในสถานที่ห่างไกล ฉันไม่สามารถเข้าถึง ILO / DRAC ได้ แต่ต้องปิดการใช้งานไฮเปอร์เธรด ระบบจะใช้ซีพียู Intel Hexmere 3.33GHz 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:ระบุ CPU linux ที่คุณต้องการปิด:

cat /proc/cpuinfo

มองหาซีพียูที่มี "รหัสแกน" เดียวกันคุณต้องการปิดหนึ่งในแต่ละคู่

ขั้นตอนที่ 2:ปิดซีพียูไฮเปอร์เธรด (ในกรณีของฉันลินุกซ์ "CPUs" สี่ตัวสุดท้ายที่เห็นโดย 8)

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
มันทำงานได้เกือบตามที่ฉันคาดไว้ แกนเสมือนถูกปิดใช้งานตอนนี้เมื่อฉันเรียกใช้เธรด cpu ที่ใช้มากโหลดแกนทางกายภาพโดย 100% แต่การใช้sysbench --num-threads=1 --test=cpu runกับ NUM เธรดที่แตกต่างกันและการเปิดและปิด HT บอกว่าการปิดการใช้งาน HT จะลดกลิ่นหอมเมื่อมีหลายเธรดและแม้ว่าจะมีเพียงเธรดเดียวก็ไม่มีประโยชน์จากการปิด HT ดังนั้นฉันขอแนะนำให้ทิ้งไว้อย่างที่มันเป็น: มันเหมาะสมที่สุด
Sergey P. aka Azure

คุณจะรู้ว่าคำสั่งเพื่อสลับพวกเขากลับมาคืออะไร? ลิงก์ที่จุดเริ่มต้นของคำตอบของคุณนั้นตายแล้ว ~ ขอบคุณ!
user189035

@ user189035: echo 1แทนที่จะecho 0เปิดใช้พวกเขาอีกครั้ง
Peter Cordes

@ SergeyP.akaazure ฉันคิดว่าสำหรับแอปพลิเคชันบริการทางการเงินเหตุผลหลักในการปิด HT ไม่ใช่ประสิทธิภาพ แต่ความปลอดภัย
Simon Richter

@SimonRichter ในขณะที่คำถามนี้ถูกเขียนเดิมมันเป็นการแสดงที่แน่นอน SMT / HT เกือบจะไม่ดีเท่างานในซีพียูในยุคนั้น สิ่งที่ Meltdown / Specter และการโจมตีของ Foradows เกิดขึ้นเมื่อไม่นานมานี้หลายปีต่อมา
Michael Hampton

14

สคริปต์เพื่อปิดใช้งานไฮเปอร์เธรดในเครื่องเริ่มต้น ...

หากต้องการปิดใช้งานไฮเปอร์เธรดฉันใส่สคริปต์ไว้ในเครื่อง /etc/rc.local มันไม่ได้สะอาดสะอ้าน แต่ติดตั้งง่ายไม่ขึ้นอยู่กับสถาปัตยกรรม cpu และควรทำงานกับการแจกจ่าย 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 ในการกระจายลินุกซ์ที่ทันสมัย ตัวอย่างเช่น:

/ sys / devices / system / cpu / cpu3 มีข้อมูลเคอร์เนลและการควบคุมสำหรับ cpu โลจิคัล 3

cat / sys / อุปกรณ์ / ระบบ / cpu / cpu3 / topology / core_id จะแสดงหมายเลขหลักของ cpu โลจิคัลนี้เป็นของ

echo "0"> / sys / อุปกรณ์ / system / cpu / cpu3 / online อนุญาตให้ปิดการใช้งาน cpu โลจิคัล 3

ทำไมถึงใช้งานได้

ฉันไม่รู้ว่าทำไม ... แต่ระบบตอบสนองมากขึ้นเมื่อปิดไฮเปอร์เธรด (บนโน้ตบุ๊ก i5 ของฉันและเซิร์ฟเวอร์ Xeon ขนาดใหญ่ที่มี 60+ คอร์) ฉันเดาว่าเกี่ยวข้องกับแคชต่อซีพียูการจัดสรรหน่วยความจำต่อซีพียูการจัดสรรตัวกำหนดตารางเวลา cpu และลำดับความสำคัญของการประมวลผลซ้ำซ้อน ฉันคิดว่าประโยชน์ของการทำไฮเปอร์เธรดนั้นมีน้ำหนักน้อยกว่าเนื่องจากความซับซ้อนในการสร้างซีพียูตัวกำหนดเวลาที่รู้วิธีใช้งาน

สำหรับฉันปัญหาของการทำไฮเปอร์เธรดคือ: ถ้าฉันเริ่มหัวข้อ cpu-เร่งรัดมากเท่าที่ฉันมีลอจิคัลคอร์ฉันจะมีการสลับบริบทอย่างรวดเร็วสำหรับงานที่เน้นหนักของ cpu แต่งานที่มีราคาแพงสำหรับงานพื้นหลังนับตั้งแต่ ซีพียูทำงานหนัก ในทางกลับกันถ้าฉันเริ่มหัวข้อ cpu-เร่งรัดมากเท่าที่ฉันมีแกนทางกายภาพฉันจะไม่มีบริบทสลับไปยังงานเหล่านั้นและสลับบริบทอย่างรวดเร็วสำหรับงานพื้นหลัง ดูเหมือนจะดี แต่งานเบื้องหลังจะพบกับตัวประมวลผลเชิงตรรกะฟรีและจะทำงานเกือบจะไม่ถูกประมวลผล มันเหมือนว่าพวกเขาแสดงตามเวลาจริง (ดี -20)

ในสถานการณ์แรกการทำไฮเปอร์เธรดคือ uselles งานเบื้องหลังจะใช้การสลับบริบทที่มีราคาแพงเพราะฉันทำไฮเปอร์เธรดสูงสุดด้วยการประมวลผลปกติ อย่างที่สองไม่สามารถยอมรับได้เพราะมากถึง 50% ของพลังซีพียูของฉันได้รับการจัดลำดับความสำคัญให้กับงานเบื้องหลัง

งาน "cpu-เร่งรัด" ที่ฉันกำลังพูดถึงคือการขุดดาต้าและปัญญาประดิษฐ์ (เซิร์ฟเวอร์ของฉัน) การปั่นการแสดงผลในคอมพิวเตอร์ราคาถูกและกลุ่ม (เพื่อร่างบ้านในอนาคตของฉัน)

นอกจากนี้ยังเป็นการคาดเดา

ฉันมีความประทับใจที่ดีกว่า แต่อาจไม่


ฉันคิดว่าสคริปต์เล็ตของฉันนั้นง่ายกว่าที่จะติดตาม
Paul M

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 หลังจากนั้น) หรือถ้าใช้ด้วงให้แก้ไข /boot/grub/menu.lst ของคุณ


ฟังก์ชั่นนี้เทียบเท่ากับการปิดใช้งาน HT ใน BIOS หรือไม่
ewwhite

ฉันไม่ทราบว่าแน่นอน แต่ใช่ฉันคาดหวังว่าจะไม่เท่ากับการปิดใช้งานบน BIOS
rems

2
นี่คือระบบ Gentoo ฉันลองnohtรายการในบรรทัดคำสั่งเคอร์เนลด้วง ระบบไม่เคารพnohtคำสั่ง เหมือนกันสำหรับ RHEL ดู: bugzilla.redhat.com/show_bug.cgi?id=440321#c9
ewwhite

1
นี้เป็นล้าสมัยอย่างน้อยตั้งแต่ Linux 2.6.18 นี้มีวัตถุประสงค์ nohtตัวเลือกเคอร์เนลจะถูกลบออก นี่เป็นเรื่องที่โชคร้ายเนื่องจาก Linux เปิดใช้งานวิธีแก้ปัญหาสำหรับ errata perf-counter errata (BJ122, BV98, HSD29) บางตัวก็ต่อเมื่อเปิดใช้ HTและสิ่งนี้เกิดขึ้นก่อนที่จะโหลด initramfs
Peter Cordes

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 )

ดังนั้นให้ใช้รายการพี่น้องเธรดทั้งหมดแยก CPU ตัวที่สองสำหรับแต่ละคู่รับรายการที่ไม่ซ้ำกันแล้วปิด

มันสมเหตุสมผลไหม

ถ้าฉันทำ "cat / proc / cpuinfo" หลังจากทำงานข้างต้นจำนวนคอร์จะลดลงครึ่งหนึ่ง


นี่คือคำตอบที่ดี ฉันต้องแก้ไขดังต่อไปนี้เพื่อใช้งานตามวัตถุประสงค์ของฉัน: echo 0 > /sys/devices/system/cpu/cpu$X/onlineกลายเป็นecho 0 | sudo tee /sys/devices/system/cpu/cpu$X/online
carbocation

5

ใหม่กว่าเมล็ดให้ตัวควบคุม Sim พร้อมกันมัลติเธรด (SMT)

คุณสามารถตรวจสอบสถานะของ SMT ด้วย;

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

เปลี่ยนสถานะด้วย

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

ตัวเลือกคือ;

  • บน
  • ปิด
  • forceoff

เราได้ทดสอบสิ่งนี้ด้วย Linux Kernel 4.4.0


สวัสดีนิคและยินดีต้อนรับสู่เว็บไซต์ ข้อมูลเกี่ยวกับการทดสอบ (และรุ่น) มีค่าทีเดียว
kubanczyk

ยอดเยี่ยมทดสอบบน Ubuntu 16.04.6 LTS
Elder Geek

4

คำตอบของ Lukas นั้นดี แต่ไม่ได้ผลสำหรับการปิดใช้งาน HT เนื่องจาก core ID ไม่สามารถใช้เพื่อระบุตัวตนของพี่น้อง 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 นั่นคือสิ่งที่ฉันทดสอบและใช้งานเพื่อจุดประสงค์ของฉัน: 2 ระบบแฮ็คซ็อกเก็ต
Anton

0

ฉันต้องรอจนกว่าฉันจะเข้าไปใน ILO / Drac พารามิเตอร์การบู๊ตของเคอร์เนลไม่สามารถใช้งานได้กับลีนุกซ์รุ่นปัจจุบัน


0

ในแพ็คเกจ libsmbios-bin (Debian, Ubuntu, ฯลฯ ) คุณมีไบนารี่ isCmosTokenActive และ enableCmosToken เมื่อใช้ร่วมกับรายการโทเค็นคุณสามารถลองดังนี้:

# 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

จากข้อมูลที่ได้รับจาก Paul Mที่นี่ฉันต้องการ "สคริปต์" ด้วยวิธีนี้

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'

แน่นอนว่ามันไม่ได้ปิดการใช้ไฮเปอร์เธรดในลักษณะเดียวกับการทำการไบออสด้วยไบออสโดยทั่วไปจะบอกเพียงแค่ตัวกำหนดเวลางานเคอร์เนลที่จะไม่ใช้คอร์บางตัวเพราะเรารู้ว่ามันเป็นของปลอม

ซอฟต์แวร์ที่สร้างสมมติฐานตามสถานะก่อนหน้า/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แต่ก็ยังขาดคำตอบที่แท้จริงสำหรับคำถาม คำสั่งเหล่านั้นใช้กับการกำหนดค่าฮาร์ดแวร์เฉพาะเท่านั้นและอาจมีผลกระทบที่ไม่ตั้งใจต่อการกำหนดค่าฮาร์ดแวร์อื่น ๆ และคำอธิบายของสิ่งที่คำสั่งเหล่านั้นทำหายไปอย่างสมบูรณ์
kasperd

ตั้งแต่ 0 หมายความว่าปิดและ 1 หมายความว่าฉันคิดว่ามันง่ายที่จะเข้าใจว่าครั้งแรกที่ปิด 4 แกน (ของปลอม 8 ใน quandocore ที่มี hyperthreading เปิด) และที่สองสลับพวกเขากลับมา ... ถ้าคุณมี DUAL แกนหมายเลขเหล่านั้นจะต้อง {3,4} แทน {4..7} ถ้าคุณใช้ octacore มันจะต้องเป็น {8..15}
Zibri

0

หัวข้อเก่า แต่มีเหตุผลที่จะลองการทดสอบนี้ ก่อนอื่นฉันไม่แน่ใจเลยว่าการปิดการใช้งาน CPU (ของปลอมเล็กน้อย) ที่รันไทม์นั้นเทียบเท่ากับการปิดการใช้งาน Hyperthreading ตอนบูต ที่กล่าวว่าฉันเห็นการเพิ่มประสิทธิภาพขนาดเล็กในแอปพลิเคชันของเรา (แต่ไม่เพียงพอที่จะเก็บไว้)

ใช้ค่าthread_siblings (ทั่วไปกับ CPU ที่มีเธรดมาก) เป็นคีย์สำหรับเปิด / ปิดการใช้งาน:

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สุดท้ายเพื่อตรวจสอบความถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.