介绍

介绍

我正在运行 ubuntu 16.04 服务器。当我使用 lscpu 命令时,我可以看到 hype threading 已启用。

我想禁用它。我经历了Ubuntu 论坛这里这里

这些讨论很好地解释了为什么超线程可能好也可能不好。但没有关于如何关闭它的明确解决方案。

有人能给出禁用超线程的步骤吗?谢谢。

答案1

介绍

这个问题很有趣。对我个人来说,这可能是几个月来最有趣的问题之一。和楼主一样,我的旧 BIOS(2012 年发明,2016 年左右更新)中没有禁用超线程的选项。

Intel Skylake 和 Kaby Lake 中的超线程错误:

任何使用英特尔 Skylake或者卡比湖处理器必须阅读几个月前出现的有关超线程的错误报告。这英国注册故事详细说明了 Debian 开发人员如何发现超线程如何导致机器崩溃和损坏。

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

本回答分为三部分:

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

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

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

设置超线程

显示屏分为两部分:

  • 在终端窗口的左半部分,set-hyper-threading使用参数 0(关闭)和 1(打开)调用脚本。
  • 右半部分conky显示 CPU 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

第二个脚本运行超线程

脚本第二次运行时,超线程打开,并且在压力测试运行时所有 CPU 编号 1-8 都飙升至 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:
#       https://askubuntu.com/questions/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内置于所有 Debian 系统(Ubuntu 是其衍生产品)。因此,您无需下载和安装任何软件包即可在 Ubuntu 中运行此脚本。

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

归功于嗨天使用于显示 CPU 拓扑的 bash 行grep "" /sys/devices/system/cpu/cpu*/topology/core_id


如果在启动前关闭超线程,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:
#       https://askubuntu.com/questions/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}

笔记:完整的 conky 资源文件可以在以下位置找到:这个答案

答案2

您可以以 root 身份或超级用户权限禁用 Linux 中的超线程:

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

您可以显示当前超线程状态和:

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

此命令打印以下之一:

on|off|forceoff|notsupported|notimplemented

或者,使用最新的内核,您可以通过在内核参数中添加nosmt或来禁用超线程。nosmt=force

此外,大多数 BIOS 固件都包含禁用超线程的选项。如果在 BIOS 中禁用了超线程,则上面的 cat 可能会返回forceoff

答案3

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

这允许您将 CPU 数量设置为物理核心数量。这可能有助于缓解由以下因素引起的威胁:MDS 漏洞在英特尔第 6 代 CPU 上。

如何:

使用 sudo(root)权限使用您最喜欢的文本编辑器打开 /etc/default/grub。

找到以以下内容开头的行GRUB_CMDLINE_LINUX_DEFAULT=

并将 maxcpus=n 添加到任何现有的内核参数中,例如常见的安静的飞溅参数(其中 n = 您的 CPU 拥有的物理核心的数量。

例如,在我信赖的 Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz 双核超线程上,我添加了最大 CPU 数=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

https://unix.stackexchange.com/questions/145645/disabling-cpu-cores-on-quad-core-processor-on-linux

答案4

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

相关内容