在Ubuntu中禁用超线程


14

我正在运行ubuntu 16.04服务器。我可以看到使用lscpu命令时启用了炒作线程。

我要禁用它。我浏览了ubuntu论坛以及这里这里

这些都是很好的讨论,为什么超线程可能不是很好。但是对于如何关闭它尚无最终解决方案。

任何人都可以给出禁用超线程的步骤吗?谢谢 。


3
您是否尝试过在BIOS中禁用它?
edwinksl

是的,找不到HT的选项
john

Answers:


9

介绍

这是个有趣的问题。对我个人来说,可能是几个月来最有趣的事情之一。与OP一样,在我的旧BIOS(发明于2012年,更新于2016年左右)中也没有禁用超级线程的选项。

英特尔Skylake和Kaby Lake中的超线程错误:

使用Intel SkylakeKaby Lake处理器的任何人都必须阅读几个月前浮出水面的有关超线程的错误报告。这个英国注册案例讲述了Debian开发人员如何发现Hyper Threading如何崩溃和破坏机器。

去年在Ask Ubuntu中报告了许多有关Skylake的问题,一个人想知道如何辨别哪些问题可能是由超线程错误引起的。

该答案分为三个部分:

  • 关闭/打开超线程时的CPU显示
  • Bash脚本自动关闭/打开超线程
  • 如果在启动超线程之前将其关闭,则Conky崩溃

关闭/打开超线程时的CPU显示

在下面,您可以查看在关闭超线程并执行CPU压力测试时的CPU利用率。大约10秒后,在打开超线程的情况下重复执行相同的脚本。最后,在脚本以超线程关闭的情况下运行10秒钟后:

设置超线程规范

显示分为两部分:

  • 在终端窗口的左半部分,set-hyper-threading使用参数0(关闭)和1(打开)调用脚本。
  • 右半部分conky显示CPUS 1到8的CPU利用率。

第一个脚本关闭超级线程

首次运行脚本时,CPU数字2、4、6和8(根据Conky)分别冻结为3%,2%,2%和2%。运行压力测试时,CPU编号1、3、5和7飙升至100%。

CPU拓扑在超线程关闭的情况下显示,并且仅报告四个内核:

/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

第二个脚本在以下位置运行Hyper Threading

第二次运行脚本时,将打开超线程,并且在运行压力测试时,所有1-8号CPU的峰值都将达到100%。

在打开超线程的情况下显示CPU拓扑,并且仅报告四个内核以及四个虚拟内核:

/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

第三个脚本关闭超级线程

请注意,第二个脚本结束后,CPU 2、4、6和8的空闲状态分别为4%,2%,3%,4%。这很重要,因为在第三个测试中,关闭“超线程”显示的CPU百分比冻结为第一次测试的4%,2%,3%,4%,而不是3%,2%,2%和2%。

因此,关闭超线程似乎只会将虚拟CPU冻结在当前状态。

还请注意,无论您打开还是关闭超线程,脚本仍会显示“支持超线程”。


Bash脚本自动关闭/打开超线程

查看下面的脚本时,请记住,Conky将CPU从1编号为8,而Linux将CPU从0编号为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

注意:该程序stress内置于所有Ubuntu派生的Debian系统中。因此,您无需下载并安装任何软件包即可在Ubuntu中运行此脚本。

如果您有双核CPU,则需要删除(或用注释掉#)控制5号和7号CPU的行。

归功于Hi-Angel的bash行grep "" /sys/devices/system/cpu/cpu*/topology/core_id显示CPU拓扑。


如果在启动超线程之前将其关闭,则Conky崩溃

为了使CPU 2、4、6、8的利用率达到最低,我尝试在启动过程中关闭超线程。我使用此脚本来做到这一点:

# 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

但是conky,如果在启动时关闭超线程,则会因分段错误而崩溃。因此,我不得不注释掉@reboot脚本中的四行。

Conky代码显示CPU利用率和负载率

如果您有兴趣在Conky中设置类似的显示,请参见以下相关代码段:

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

注意:上面的Nvidia代码从未经过测试,因为我还没有在Ubuntu下使用Nvidia GPU。现在任何一年:)


1
抱歉,但noht不存在。我什至偶尔碰巧通过linux-4.13-rc1来源对这个选项进行了grep。但是,我当然理解可能会使您感到困惑的问题:dat bugreport抱怨该选项不起作用,然后将其关闭为nextrelease,就像他们修复了某些问题一样。但是,如果您阅读注释,您将看到的唯一用途noht是手工制作的脚本,该脚本检查内核命令行中的选项,然后通过/sys/文件系统禁用内核。IOW noht是没用的。
Hi-Angel

@ Hi-Angel感谢您指出没有必要。我在没有它的情况下进行了测试,脱机核心从2,2,5,5%(含Noht)翻倍至5,5,10,10%(不含Noht)。今晚我将做更多测试。我搜索了内核参数文档,但找不到对的任何引用noht
WinEunuuchs2Unix

顺带一提,索引没有机器/人类语言:)要解决从0、1甚至是特定数字(如MiniZinc)开始的索引的混淆,最好考虑索引集,即a从一组索引到另一组。将其抽象化可以让您更轻松地注意到与数据内容相关的某些东西(不代表索引)在经过一些扭曲之后实际上可以用于索引。优点来自于牢记不受内存布局和其他限制约束的概念。
Hi-Angel

@ Hi-Angel我猜大概在“开始位置”和“偏移”之间比较。无论如何,我将根据测试和编码的最后两天来重写此答案,因此我们的评论将很快过时……
WinEunuuchs2Unix

6

最近的内核支持maxcpus 内核参数。

这使您可以将cpus的数量设置为物理核心的数量。这可能有助于缓解家族6的Intel CPU上的MDS漏洞造成的威胁。

怎么样:

具有sudo(root)特权的用户,使用您喜欢的文本编辑器打开/ etc / default / grub。

查找以GRUB_CMDLINE_LINUX_DEFAULT =开头的行

并将maxcpus = n添加到任何现有的内核参数,例如常见的安静启动参数(其中n =您的cpu拥有的物理内核数)。

例如,在我信任的具有超线程功能的Intel(R)i3-3220 CPU @ 3.30GHz双核上,我添加了maxcpus = 2以在启动时关闭超线程。

保存文件,然后发出命令sudo update-grub并重新启动。

您可以通过发出以下命令来确认成功,该命令lscpu | grep "per core"应提供如下输出:

Thread(s) per core: 1

在内核4.4.0上测试

资料来源:

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
有趣的链接。感谢分享。
WinEunuuchs2Unix

@ WinEunuuchs2Unix我的荣幸。一直渴望帮助!
极客长老

4

您可以通过以下方式在Linux中以超级用户或超级用户权限禁用超线程:

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

您可以使用以下命令显示当前的超线程状态

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

此命令显示以下内容之一:

on|off|forceoff|notsupported|notimplemented

另外,大多数BIOS固件还包括一个用于禁用超线程的选项。如果在BIOS中将其禁用,则上面的猫可能会返回forceoff


您是否尝试过这个在系统启动时禁用超线程?
年长者怪杰

1
@ElderGeek不,我没有尝试过使用maxcpus=内核参数来禁用超线程。主要是因为我找不到有关它与超线程内核交互的任何正式文档。如果指定,是否保证始终禁用超线程maxcpus=#real_cores?还是在某些系统上仍启用HT的情况下最终获得了一半的实际内核?同样,maxcpus=在具有不同核心数量的计算机之间不能移植一种设置。对于不同的机器维持该参数的变化将是乏味且容易出错的。
maxschlepzig

以我的经验,如果您指定maxcpus =#real_cores,则总是禁用超线程,当然您可以信任输出。lscpu | grep "per core"关于可移植性,您有一个很重要的观点,但是,另一方面,设置内核参数似乎并不太麻烦对我来说。
年长者怪杰

2

这是一个脚本,用于识别ht-core,并在线/离线切换它们。

#!/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,也许您可​​以将此添加到出色的答案中。


我必须对列表进行数字排序以使其正常工作:for i in $(find /sys/devices/system/cpu/cpu[0-9]* -maxdepth 0 -type d |sort -V); do
neuhaus

2

中的maxcpus=n参数GRUB_CMDLINE_LINUX_DEFAULT=无法正常工作。它给了我2个内核和4个线程,而不是4个内核和4个线程。

我找到了解决方案。

添加mitigations=auto,nosmtGRUB_CMDLINE_LINUX_DEFAULT=代替

在Linux 4.4.0的Ubuntu 16.04 LTS上进行了测试。

资料来源:https : //wiki.ubuntu.com/SecurityTeam/KnowledgeBase/MDS


1

对于主板托管多个CPU插槽的系统,需要一种在内核中查找超线程对的更健壮的方法,因为core_id是重复的。这是在具有两个8核Xeon芯片的系统上的版本(来自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

出于各种目的,您可能还需要查看文件

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

0

如果您阅读过讨论,那么您可能知道禁用它通常是不合理的,因此我假设您出于学习目的而希望使用它。

HT的想法是为每个物理核心(所谓的虚拟核心)拥有多组CPU寄存器。没有“更好”的虚拟核心,它们是相同的。有了这些知识,您就可以禁用虚拟内核,但每个物理内核除外。

首先,您想知道哪些虚拟核心对属于/sys/文件系统中的哪个物理核心。您可以core_id为此使用文件:

λ 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

从输出中可以推断出cpu0 + cpu2包含在一个物理内核中,cpu1 + cpu3包含在另一个物理内核中。现在提升特权,并使用echo命令禁用每对特权:

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

请注意,cpu0没有“在线”文件,因此无法禁用,因此我禁用了cpu2。


0

如果thread_siblings_list中的分隔符不是逗号,则@ visit1985的答案不起作用(例如,在我的AMD Ryzen系统上就是这种情况)。

这是一个关闭超线程的脚本,该脚本可与任何分隔符一起使用:

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

这是打开超线程的一种方法:

#!/bin/bash

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

请问这个方法您Ryzen CPU的工作?
年长者怪杰
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.