Vô hiệu hóa siêu phân luồng từ bên trong Linux (không có quyền truy cập vào BIOS)


26

Tôi có một hệ thống chạy một ứng dụng giao dịch tài chính tại một cơ sở từ xa. Tôi không có quyền truy cập vào ILO / DRAC, nhưng cần phải vô hiệu hóa siêu phân luồng. Hệ thống này chạy CPU lõi tứ Intel X580 3,33GHz X5680. Tôi có thể khởi động lại, nhưng muốn đảm bảo rằng hệ thống không cho phép siêu phân luồng do vấn đề về hiệu suất. Có cách nào rõ ràng để làm điều này từ bên trong Linux không?

Chỉnh sửa: Lệnh nohtđược thêm vào dòng lệnh khởi động kernel không hoạt động. Tương tự cho RHEL.

Xem: https://ormszilla.redhat.com/show_orms.cgi?id=440321#c9

Câu trả lời:


21

Bạn có thể làm điều này trong thời gian chạy nếu bạn muốn. Tôi tìm thấy một giải pháp tốt được mô tả ở đây: http://www.absolTHERtech.com/2011/08/01/how-to-disable-cpu-cores-in-linux/

Bước 1: Xác định CPU linux mà bạn muốn tắt:

cat /proc/cpuinfo

Hãy tìm các CPU có cùng "id lõi", bạn muốn tắt một trong mỗi cặp.

Bước 2: Tắt CPU siêu phân luồng (trong trường hợp của tôi là bốn CPU cuối cùng trong tổng số 8 "CPU" mà Linux thấy)

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

Bạn có thể thiết lập cho mình một tập lệnh mà bạn chạy ngay sau khi hệ thống khởi động.


1
Nó hoạt động gần như tôi mong đợi. lõi ảo bị vô hiệu hóa, bây giờ khi tôi thực thi một luồng tiêu thụ cpu, nó sẽ tải lõi vật lý 100%. Nhưng việc sử dụng sysbench --num-threads=1 --test=cpu runvới các chủ đề num và HT khác nhau được bật và tắt nói rằng việc vô hiệu hóa HT sẽ làm giảm mùi thơm khi có nhiều luồng và ngay cả khi chỉ có một luồng thì không có lợi ích gì khi tắt HT. Vì vậy, tôi đề nghị để nguyên như vậy: nó là tối ưu.
Serge P. hay còn gọi là azure

Bạn có biết lệnh để bật chúng trở lại là gì không? Liên kết ở đầu câu trả lời của bạn đã chết ~. Cảm ơn!
dùng189035

@ user189035: echo 1thay vì echo 0nên bật lại.
Peter Cordes

@ SergeyP.akaazure, tôi nghĩ đối với một ứng dụng dịch vụ tài chính, lý do chính để tắt HT không phải là hiệu suất, mà là bảo mật.
Simon Richter

@SimonRichter Tại thời điểm câu hỏi này ban đầu được viết, nó thực sự là hiệu suất. SMT / HT gần như không tốt ở một số khối lượng công việc trên CPU trong thời đại đó. Điều Meltdown / Spectre, và các cuộc tấn công Foreshadow gần đây hơn, đã xảy ra nhiều năm sau đó.
Michael Hampton

14

Một tập lệnh để vô hiệu hóa siêu phân luồng khi khởi động máy ...

Để vô hiệu hóa siêu phân luồng, tôi bao gồm một tập lệnh trên máy /etc/rc.local. Nó không phải là exaclty sạch, nhưng dễ cài đặt, độc lập với kiến ​​trúc cpu và nên hoạt động trên bất kỳ bản phân phối linux hiện đại nào.

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;    

Làm thế nào điều này hoạt động?

Thông tin và điều khiển nhân Linux có thể được truy cập dưới dạng tệp trong thư mục / sys trên các bản phân phối linux hiện đại. Ví dụ:

/ sys / thiết bị / system / cpu / cpu3 chứa thông tin kernel và các điều khiển cho logic cpu 3.

cat / sys / thiết bị / system / cpu / cpu3 / topology / core_id sẽ hiển thị số lõi mà cpu logic này thuộc về.

echo "0"> / sys / thiết bị / hệ thống / cpu / cpu3 / trực tuyến cho phép vô hiệu hóa cpu 3 logic.

Tại sao nó hoạt động?

Tôi không biết chính xác lý do tại sao ... nhưng hệ thống trở nên nhạy hơn với việc siêu phân luồng (trên máy tính xách tay i5 của tôi và các máy chủ Xeon lớn với hơn 60 lõi). Tôi đoán điều đó có liên quan đến bộ nhớ per-cpu, cấp phát bộ nhớ per-cpu, phân bổ bộ lập lịch cpu và xử lý các ưu tiên phức tạp lặp lại. Tôi nghĩ rằng những lợi ích của siêu phân luồng là vượt trội bởi sự phức tạp của việc tạo các bộ lập lịch cpu biết cách sử dụng nó.

Đối với tôi, vấn đề với siêu phân luồng là: Nếu tôi bắt đầu nhiều luồng xử lý cpu như tôi có lõi logic, tôi sẽ có các chuyển đổi ngữ cảnh nhanh cho các tác vụ chuyên sâu cpu, nhưng đắt tiền cho các tác vụ nền vì siêu phân luồng hoàn toàn bị tiêu thụ bởi nhiệm vụ chuyên sâu cpu. Mặt khác, nếu tôi bắt đầu nhiều luồng xử lý cpu như tôi có lõi vật lý, tôi sẽ không có chuyển đổi ngữ cảnh cho các tác vụ đó và chuyển đổi ngữ cảnh nhanh cho các tác vụ nền. Có vẻ tốt, nhưng các tác vụ nền sẽ tìm thấy bộ xử lý logic miễn phí và sẽ chạy gần như hoàn toàn. Nó giống như họ là hiệu suất thời gian thực (đẹp -20).

Trong kịch bản đầu tiên, siêu phân luồng là uselles, các tác vụ nền sẽ sử dụng các chuyển đổi ngữ cảnh đắt tiền vì tôi đã tối đa hóa siêu phân luồng với xử lý thông thường. Thứ hai là không thể chấp nhận được vì có tới 50% năng lượng cpu của tôi được ưu tiên cho các tác vụ nền.

Các nhiệm vụ "chuyên sâu về cpu" mà tôi đang nói đến là các máy chủ ủy quyền và khai thác dữ liệu trí tuệ nhân tạo (công việc của tôi). Kết xuất máy xay trong các máy tính và cụm giá rẻ (để phác họa ngôi nhà tương lai của tôi).

Ngoài ra, đây là phỏng đoán.

Tôi có ấn tượng là tốt hơn, nhưng nó có thể không.


Tôi nghĩ kịch bản của tôi dễ theo dõi hơn một chút.
Paul M

9

Đối với các nhân thực sự cũ (Linux 2.6.9 trở lên), hãy nối tham số noht vào kernel khi khởi động.

Tùy chọn dòng lệnh kernel này đã bị xóa kể từ ít nhất là Linux 2.6.18 .


Từ 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. 

Nếu sử dụng lilo, bạn chỉnh sửa /etc/lilo.conf (và chạy lilo sau đó) hoặc nếu sử dụng grub thì hãy chỉnh sửa /boot/grub/menu.lst của bạn.


Đây có phải là chức năng tương đương với vô hiệu hóa HT trong BIOS?
ewwhite

Tôi không biết điều đó chắc chắn, nhưng vâng, tôi hy vọng noht tương đương với việc vô hiệu hóa nó trên BIOS.
rems 15/2

2
Đây là một hệ thống Gentoo. Tôi đã thử nohtmục trong dòng lệnh grub kernel. Hệ thống đã không tôn trọng nohtlệnh. Tương tự cho RHEL. Xem: bugzilla.redhat.com/show_orms.cgi?id=440321#c9
ewwhite

1
Điều này đã lỗi thời vì ít nhất là Linux 2.6,18 . Các nohttùy chọn hạt nhân đã được gỡ bỏ. Điều này thật đáng tiếc, bởi vì Linux cho phép giải quyết một số lỗi truy cập hoàn hảo của Haswell (BJ122, BV98, HSD29) chỉ khi HT bật và điều này xảy ra trước khi initramfs thậm chí được tải.
Peter Cordes

9

Bạn có thể sử dụng "thread_siblings_list" cho mỗi lõi để tắt lõi thứ hai trong cặp HT.

Các đường ống lệnh sau đây là hacky, không được tối ưu hóa và được thực hiện theo cách này hy vọng sẽ làm cho nó dễ hiểu hơn.

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 )

vì vậy, lấy tất cả các danh sách anh chị em luồng, trích xuất CPU thứ hai cho mỗi cặp, lấy một danh sách duy nhất và sau đó tắt chúng.

Điều này có nghĩa không?

nếu tôi thực hiện "cat / Proc / cpuinfo" sau khi chạy ở trên, số lượng lõi giảm đi một nửa.


Đây là một câu trả lời tuyệt vời. Tôi đã phải sửa đổi nó như sau để hoạt động cho mục đích của mình: echo 0 > /sys/devices/system/cpu/cpu$X/onlinetrở thànhecho 0 | sudo tee /sys/devices/system/cpu/cpu$X/online
carbocation

5

Các hạt nhân mới hơn cung cấp điều khiển Đa luồng đồng thời (SMT).

Bạn có thể kiểm tra trạng thái của SMT với;

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

Thay đổi trạng thái với

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

Tùy chọn là;

  • trên
  • tắt
  • bắt buộc

Chúng tôi đã thử nghiệm điều này với Linux Kernel 4.4.0


Xin chào Nick và chào mừng đến với trang web. Thông tin về các bài kiểm tra (và phiên bản) là khá có giá trị.
kubanchot

Tuyệt vời, Đã thử nghiệm trên Ubuntu 16.04.6 LTS
Elder Geek

4

Câu trả lời của Lukas rất hay nhưng không thực sự hiệu quả trong việc vô hiệu hóa HT vì ID lõi không thể phục vụ cho việc nhận dạng anh chị em HT. Kịch bản này hoạt động thay thế:

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

kịch bản của bạn là một biến thể của tôi. chúng tôi sẽ phải kiểm tra xem điều gì sẽ xảy ra nếu bạn có nhiều CPU, để chắc chắn.
Paul M

@PaulM Đó chính xác là nơi tôi đã thử nghiệm và sử dụng nó cho mục đích của mình: hệ thống Haswell 2 ổ cắm.
Anton

0

Tôi phải đợi cho đến khi tôi có thể vào ILO / Drac. Các tham số khởi động kernel không hoạt động trên các bản phân phối Linux hiện tại.


0

Trong gói libsmbios-bin (Debian, Ubuntu, v.v.), bạn có các nhị phân isCmosTokenActive và activCmosToken. Cùng với danh sách mã thông báo , sau đó bạn có thể thử một cái gì đó như thế này:

# 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

Sau đó kích hoạt mã thông báo CPU_Hyperthreading_Disable:

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

Kiểm chứng:

# 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

Bây giờ, câu hỏi lớn là liệu bạn có đơn giản chỉ cần khởi động lại để điều này có hiệu lực hay không, hoặc nếu cần một chu kỳ toàn bộ năng lượng. Hãy thử nó và xem làm thế nào nó đi!


0

Dựa trên thông tin được cung cấp bởi Paul M tại đây, tôi sẽ "viết kịch bản" theo cách này:

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'

Tất nhiên, nó không tắt siêu phân luồng theo nghĩa tương tự như việc mày mò với BIOS sẽ làm , về cơ bản, nó chỉ cho bộ lập lịch tác vụ kernel không sử dụng một số lõi vì chúng ta biết chúng là giả.

Phần mềm đưa ra giả định dựa trên trạng thái trước đó /prochoặc /syshệ thống phụ vẫn có thể đang chạy dưới mức tối ưu hoặc thậm chí không thành công do thay đổi thời gian chạy này do đó có thể cần phải khởi động lại. Ví dụ, tôi nhận thấy irqbalancedễ bị thất bại trong hoàn cảnh đó.


0

Vô hiệu hóa HT:

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

Kích hoạt HT:

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

Lưu ý: Điều này không thực sự vô hiệu hóa HyperThreading nhưng họ vô hiệu hóa các lõi "giả" thu được kết quả gần như tương tự.


Tôi thích cách bạn đang sử dụng tee, nhưng điều này vẫn không cung cấp câu trả lời thực sự cho câu hỏi. Những lệnh này chỉ áp dụng cho các cấu hình phần cứng cụ thể và có thể có tác dụng ngoài ý muốn đối với các cấu hình phần cứng khác. Và một lời giải thích về những gì các lệnh đó làm là hoàn toàn không có.
kasperd

Vì 0 có nghĩa là tắt và 1 có nghĩa là bật, tôi nghĩ thật dễ hiểu khi lần đầu tiên tắt 4 lõi (của 8 giả trên một quandocore với siêu phân luồng) và lần thứ hai sẽ bật lại ... Nếu bạn có DUAL số lõi đó phải là {3,4} thay vì {4..7} Nếu bạn sử dụng octacore, số đó phải là {8..15}
Zibri

0

Chủ đề cũ, nhưng có lý do để thử thí nghiệm này. Đầu tiên, tôi không chắc chắn rằng việc vô hiệu hóa CPU (hơi giả) trong thời gian chạy thực sự tương đương với việc vô hiệu hóa Hyperthreading khi khởi động. Điều đó nói rằng, tôi đã thấy một sự gia tăng hiệu suất nhỏ trong ứng dụng của chúng tôi. (Nhưng không đủ để giữ.)

Đã sử dụng giá trị thread_siblings (phổ biến cho CPU siêu phân luồng) làm khóa để bật / tắt:

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 

Hãy thử lệnh w / o sudo sh cuối cùng để xác minh chính xác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.