Vô hiệu hóa siêu phân luồng trong Ubuntu


13

Tôi đang chạy máy chủ Ubuntu 16.04. Tôi có thể thấy rằng luồng hype được kích hoạt khi tôi sử dụng lệnh lscpu.

Tôi muốn vô hiệu hóa nó. Tôi đã đi qua các diễn đàn Ubuntuở đâyở đây .

Đây là những cuộc thảo luận tốt tại sao siêu phân luồng có thể không tốt. Nhưng không có giải pháp dứt khoát về cách tắt nó.

Bất kỳ có thể đưa ra các bước để vô hiệu hóa siêu phân luồng? Cảm ơn .


3
Bạn đã thử vô hiệu hóa nó trong BIOS chưa?
edwinksl

có, không thể tìm thấy tùy chọn cho HT
john

Câu trả lời:


9

Giới thiệu

Đây là một câu hỏi thú vị. Có lẽ là một trong những điều thú vị nhất trong tháng đối với cá nhân tôi. Giống như OP, không có tùy chọn nào để vô hiệu hóa Hyper Threading trong BIOS cũ của tôi (được phát minh năm 2012, cập nhật 2016 hoặc hơn).

Lỗi siêu phân luồng trong Intel Skylake và Kaby Lake:

Bất cứ ai sử dụng bộ xử lý Intel Skylake hoặc Kaby Lake đều phải đọc các báo cáo lỗi về Hyper Threading xuất hiện vài tháng trước. Câu chuyện đăng ký tại Vương quốc Anh này giải thích cách các nhà phát triển Debian phát hiện ra cách Hyper Threading có thể sập và làm hỏng máy.

Có rất nhiều vấn đề với Skylake được báo cáo trong Ask Ubuntu trong năm ngoái và người ta tự hỏi làm thế nào để nhận ra vấn đề nào có thể do lỗi Hyper Threading gây ra.

Câu trả lời này được chia thành ba phần:

  • Hiển thị CPU khi Hyper-Threading bị tắt / bật
  • Tập lệnh Bash để tự động tắt / bật siêu phân luồng
  • Sự cố Conky nếu Hyper Threading bị tắt trước khi bắt đầu

Hiển thị CPU khi Hyper-Threading bị tắt / bật

Dưới đây bạn có thể thấy việc sử dụng CPU khi siêu phân luồng bị tắt và kiểm tra căng thẳng CPU được thực hiện. Khoảng 10 giây sau, kịch bản tương tự được lặp lại với siêu phân luồng được bật. Cuối cùng, 10 giây sau đó, đoạn script được chạy với siêu phân luồng được tắt lại:

Đặt siêu phân luồng noht

Màn hình được chia thành hai phần:

  • Ở nửa bên trái, cửa sổ đầu cuối gọi tập lệnh set-hyper-threadingvới tham số 0 (tắt) và sau đó 1 (bật).
  • Ở nửa bên phải conkyhiển thị mức sử dụng phần trăm CPU của CPUS 1 đến 8.

Kịch bản đầu tiên chạy Hyper Threading tắt

Lần đầu tiên tập lệnh chạy CPU Số 2, 4, 6 & 8 (theo Conky) bị đóng băng ở mức 3%, 2%, 2% và 2%. Số CPU 1, 3, 5 và 7 tăng vọt lên 100% trong khi kiểm tra căng thẳng được chạy.

Cấu trúc liên kết CPU được hiển thị với siêu phân luồng đã tắt và chỉ có bốn lõi được báo cáo:

/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

Kịch bản thứ hai chạy Hyper Threading trên

Lần thứ hai tập lệnh được chạy Hyper-Threading được bật và tất cả các số CPU tăng vọt lên 100% trong khi kiểm tra căng thẳng được chạy.

Cấu trúc liên kết CPU được hiển thị với siêu phân luồng được bật và chỉ có bốn lõi cộng và bốn lõi ảo được báo cáo:

/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

Kịch bản thứ ba chạy Hyper Threading tắt

Lưu ý làm thế nào sau khi tập lệnh thứ hai kết thúc CPU 2, 4, 6 và 8 không hoạt động ở mức 4%, 2%, 3%, 4%. Điều này rất quan trọng vì trong thử nghiệm thứ ba, tắt Hyper-Threading cho thấy các phần trăm CPU bị đóng băng ở mức 4%, 2%, 3%, 4% thay vì 3%, 2%, 2% và 2% từ thử nghiệm đầu tiên.

Do đó, tắt siêu phân luồng dường như chỉ đóng băng các CPU ảo ở trạng thái hiện tại.

Cũng lưu ý cho dù bạn bật hay tắt Hyper-Threading thì tập lệnh vẫn hiển thị "Hyper Threading được hỗ trợ".


Tập lệnh Bash để tự động tắt / bật siêu phân luồng

Khi xem đoạn script dưới đây, hãy nhớ rằng Conky đánh số CPU từ 1 đến 8 nhưng Linux đánh số CPU từ 0 đến 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

LƯU Ý: Chương trình stressđược tích hợp vào tất cả các hệ thống Debian mà Ubuntu là một dẫn xuất của. Do đó, bạn không phải tải xuống và cài đặt bất kỳ gói nào để chạy tập lệnh này trong Ubuntu.

Nếu bạn có CPU lõi kép, bạn cần xóa (hoặc nhận xét với #) các dòng điều khiển số CPU 5 và 7.

Tín dụng cho Hi-Angel cho dòng bash grep "" /sys/devices/system/cpu/cpu*/topology/core_idhiển thị cấu trúc liên kết CPU.


Sự cố Conky nếu Hyper Threading bị tắt trước khi bắt đầu

Để có được CPU 2, 4, 6, 8 đến mức sử dụng phần trăm thấp nhất có thể, tôi đã thử tắt Hyper-Threading trong khi khởi động. Tôi đã sử dụng kịch bản này để làm điều đó:

# 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

Tuy nhiên, conkysự cố với lỗi phân đoạn nếu siêu phân luồng bị tắt khi khởi động. Vì vậy, tôi đã phải bình luận ra bốn @rebootdòng trong kịch bản.

Conky Code để hiển thị mức sử dụng phần trăm CPU và hệ số tải

Nếu bạn quan tâm đến việc thiết lập một màn hình tương tự trong Conky thì đây là đoạn mã có liên quan:

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

LƯU Ý: Mã Nvidia ở trên chưa bao giờ được kiểm tra vì tôi chưa có GPU Nvidia hoạt động trong Ubuntu. Bất cứ năm nào bây giờ :)


1
Xin lỗi, nhưng nohtkhông tồn tại. Tôi thậm chí đã tham gia tùy chọn thông qua các nguồn linux-4.13-RC1 mà thỉnh thoảng tôi có. Tuy nhiên tôi chắc chắn hiểu những gì có thể làm bạn bối rối: dat bugreport phàn nàn rằng tùy chọn này không hoạt động, và sau đó nó đóng nextreleasenhư thể họ đã sửa một cái gì đó. Tuy nhiên, nếu bạn đọc các bình luận, bạn sẽ thấy rằng việc sử dụng duy nhất nohtlà cho một tập lệnh thủ công kiểm tra dòng lệnh kernel cho tùy chọn, sau đó vô hiệu hóa các lõi thông qua /sys/hệ thống tập tin. IOW nohtlà vô dụng.
Hi-Angel

@ Hi-Angel Cảm ơn bạn đã chỉ ra rằng nó không cần thiết. Tôi đã thử nghiệm mà không có nó và các lõi ngoại tuyến tăng gấp đôi từ 2,2,5,5% (với noht) lên 5,5,10,10% (không có noht). Tôi sẽ làm thêm thử nghiệm tối nay. Tôi đã tìm kiếm tài liệu tham số kernel và không thể tìm thấy bất kỳ tài liệu tham khảo nào noht.
WinEunuuchs2Unix

Bên cạnh đó, không có ngôn ngữ Máy / Con người để lập chỉ mục :) Để giải quyết sự nhầm lẫn với các chỉ số bắt đầu từ 0, 1 hoặc thậm chí là một số cụ thể (như trong MiniZinc) , tốt hơn là bạn nên nghĩ về các bộ chỉ mục , tức là từ chối một tập hợp các chỉ số sang một tập hợp khác. Tóm tắt nó cho phép bạn ghi chú dễ dàng hơn khi một số liên quan đến một công cụ dữ liệu, không đại diện cho các chỉ số, thực sự có thể được sử dụng để lập chỉ mục sau khi bị vặn một chút. Lợi thế đến từ việc có một khái niệm không ràng buộc từ bố cục bộ nhớ và các hạn chế khác.
Hi-Angel

@ Hi-Angel So sánh tương tự giữa "Vị trí bắt đầu" và "Offset" tôi đoán. Dù sao tôi cũng sẽ viết lại câu trả lời này dựa trên hai ngày thử nghiệm và mã hóa cuối cùng để nhận xét của chúng tôi sẽ sớm bị lỗi thời ...
WinEunuuchs2Unix

6

Các hạt nhân gần đây hỗ trợ tham số kernel maxcpus .

Điều này cho phép bạn đặt số lượng cpus thành số lõi vật lý. Điều này có thể hữu ích để giúp giảm thiểu các mối đe dọa gây ra bởi các lỗ hổng MDS trên CPU Intel từ gia đình 6.

Làm sao:

với đặc quyền sudo (root) mở / etc / default / grub với trình soạn thảo văn bản yêu thích của bạn.

Tìm dòng bắt đầu bằng GRUB_CMDLINE_LINUX_DEFAULT =

và thêm maxcpus = n vào bất kỳ tham số kernel hiện có nào, chẳng hạn như các tham số giật gân yên tĩnh phổ biến (trong đó n = số lõi vật lý mà cpu của bạn có.

Ví dụ, trên lõi kép Intel (R) Core (TM) i3-3220 CPU @ 3.30GHz đáng tin cậy của tôi với siêu phân luồng, tôi đã thêm maxcpus = 2 để tắt siêu phân luồng khi khởi động.

Lưu tệp và sau đó phát lệnh sudo update-grubvà khởi động lại.

Bạn có thể xác nhận thành công bằng cách ban hành lệnh lscpu | grep "per core"sẽ cung cấp đầu ra như thế này:

Thread(s) per core: 1

Đã thử nghiệm trên kernel 4.4.0

Nguồn:

https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/kernel-paramameter.txt

https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html

/unix/145645/diseac-cpu-cores-on-quad-core- Processor-on-linux


1
Liên kết thú vị. Cám ơn vì đã chia sẻ.
WinEunuuchs2Unix

@ WinEunuuchs2Unix Niềm vui của tôi. Luôn sẵn sàng giúp đỡ!
Anh Cả Geek

4

Bạn có thể vô hiệu hóa siêu phân luồng trong Linux dưới quyền root hoặc với các đặc quyền siêu người dùng với:

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

Bạn có thể hiển thị trạng thái siêu phân luồng hiện tại với:

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

Lệnh này in một trong:

on|off|forceoff|notsupported|notimplemented

Ngoài ra, hầu hết các phần mềm BIOS cũng bao gồm một tùy chọn để vô hiệu hóa siêu phân luồng. Nếu nó bị vô hiệu hóa trong BIOS, con mèo ở trên có khả năng trở lại forceoff.


Bạn đã thử điều này để vô hiệu hóa siêu luồng khi khởi động chưa?
Anh Cả Geek

1
@ElderGeek không, tôi chưa thử maxcpus=tham số kernel để vô hiệu hóa siêu phân luồng. Chủ yếu là vì tôi không thể tìm thấy bất kỳ tài liệu chính thức nào về sự tương tác của nó với các lõi siêu phân luồng. Có đảm bảo luôn luôn vô hiệu hóa siêu phân luồng nếu bạn chỉ định maxcpus=#real_cores? Hoặc bạn có thể kết thúc với một nửa số lõi thực với HT vẫn được bật trên một số hệ thống? Ngoài ra, một maxcpus=cài đặt không thể di chuyển giữa các máy có số lượng lõi khác nhau. Việc duy trì các biến thể của tham số này cho các máy khác nhau sẽ rất tẻ nhạt và dễ bị lỗi.
maxschlepzig

Theo kinh nghiệm của tôi, tôi luôn bị vô hiệu hóa siêu phân luồng nếu bạn chỉ định maxcpus = # real_cores được cung cấp tất nhiên là bạn tin tưởng đầu ra của lscpu | grep "per core"Bạn tạo một điểm vaild liên quan đến tính di động, tuy nhiên, mặt trái đặt tham số kernel một khi không thực sự quá khó với tôi.
Anh Cả Geek

2

Đây là một kịch bản để xác định các lõi ht và chuyển chúng trực tuyến / ngoại tuyến.

#!/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 , có lẽ bạn có thể thêm câu này vào câu trả lời tuyệt vời của bạn.


Tôi đã phải sắp xếp số lượng danh sách để làm cho nó hoạt động chính xác:for i in $(find /sys/devices/system/cpu/cpu[0-9]* -maxdepth 0 -type d |sort -V); do
neuhaus

2

Các maxcpus=ntham số trong GRUB_CMDLINE_LINUX_DEFAULT=không hoạt động đúng. Nó để lại cho tôi 2 lõi và 4 luồng thay vì 4 lõi 4 luồng.

Tôi tìm thấy một giải pháp.

Thêm vào mitigations=auto,nosmtđể GRUB_CMDLINE_LINUX_DEFAULT=thay thế

Đã thử nghiệm trên Ubuntu 16.04 LTS với Linux 4.4.0.

Nguồn: https://wiki.ubfox.com/SecurityTeam/KnowledgeBase/MDS


1

Một cách mạnh mẽ hơn để tìm trong kernel cho các cặp siêu phân luồng là cần thiết cho các hệ thống nơi bo mạch chủ lưu trữ nhiều ổ cắm CPU vì core_id được sao chép. Đây là phiên bản của tôi trên một hệ thống có hai chip Xeon 8 lõi (ví dụ từ 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

Đối với các mục đích khác nhau, bạn cũng có thể muốn tìm trong các tập tin

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

0

Nếu bạn đã đọc các cuộc thảo luận, thì có lẽ bạn biết rằng thường thì không hợp lý để vô hiệu hóa, vì vậy tôi sẽ cho rằng bạn muốn nó cho mục đích học tập.

Ý tưởng của HT là có nhiều bộ thanh ghi CPU cho mọi lõi vật lý (cái gọi là lõi ảo) . Không có lõi ảo "tốt hơn", chúng giống hệt nhau. Được trang bị kiến ​​thức này, bạn có thể vô hiệu hóa các lõi ảo ngoại trừ một lõi cho mọi vật lý.

Trước tiên, bạn muốn biết cặp lõi ảo nào thuộc về lõi vật lý nào trong /sys/hệ thống tập tin. Bạn có thể sử dụng core_idtập tin cho điều đó:

λ 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

Từ đầu ra, bạn có thể suy ra rằng cpu0 + cpu2 được chứa trong một lõi vật lý và cpu1 + cpu3 trong lõi kia. Bây giờ nâng cao đặc quyền và sử dụng echolệnh để vô hiệu hóa một trong mỗi cặp:

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

Lưu ý rằng cpu0 không có tệp "trực tuyến" và không thể bị vô hiệu hóa, vì vậy tôi đã vô hiệu hóa cpu2.


0

Câu trả lời của @ visit1985 không hoạt động nếu dấu phân cách trong thread_siblings_list không phải là dấu phẩy (ví dụ: trường hợp trên hệ thống AMD Ryzen của tôi).

Đây là một kịch bản để tắt siêu phân luồng hoạt động với bất kỳ dấu phân cách nào:

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

Và đây là một để bật siêu phân luồng:

#!/bin/bash

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

Liệu phương pháp này làm việc trên CPU Ryzen của bạn?
Anh Cả Geek
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.