从Linux内部禁用超线程(无法访问BIOS)


26

我有一个在远程设施上运行金融交易应用程序的系统。我无权访问ILO / DRAC,但需要禁用超线程。该系统运行Intel Westmere 3.33GHz X5680六核CPU。我可以重新启动,但要确保由于性能问题而导致系统未启用超线程。有没有从Linux内部执行此操作的干净方法?

编辑:noht添加到内核引导命令行的指令不起作用。与RHEL相同。

请参阅:https//bugzilla.redhat.com/show_bug.cgi?id = 440321#c9

Answers:


21

您可以根据需要在运行时执行此操作。我在这里找到了一个不错的解决方案:http : //www.absolutelytech.com/2011/08/01/how-to-disable-cpu-cores-in-linux/

步骤1:确定您要关闭的Linux CPU:

cat /proc/cpuinfo

查找具有相同“核心ID”的CPU,您要关闭每对CPU中的一个。

步骤2:关闭超线程CPU(在我的情况下,是Linux看到的总共8个“ CPU”中的最后四个)

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具有不同数量的线程并打开和关闭HT的情况表示,当有多个线程时,禁用HT会降低性能,即使只有一个线程,关闭HT也无济于事。因此,我建议保留原样:这是最佳选择。
Sergey P.又名天青

您知道将其重新打开的命令是什么吗?您答案开头的链接已消失〜。谢谢!
user189035 '16

@ user189035:echo 1而不是echo 0应该重新打开它们。
彼得·科德斯

@ SergeyP.akaazure,我认为对于金融服务应用程序,关闭HT的主要原因不是性能,而是安全性。
西蒙·里希特

@SimonRichter在最初编写此问题时,确实是性能。SMT / HT在那个时代的CPU上的某些工作负载上几乎不那么出色。几年后发生了Meltdown / Spectre事件,以及最近的Foreshadow攻击。
迈克尔·汉普顿

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内核信息和控件可以作为现代linux发行版上/ sys目录中的文件进行访问。例如:

/ sys / devices / system / cpu / cpu3 包含内核信息和逻辑cpu 3的控件。

cat / sys / devices / system / cpu / cpu3 / topology / core_id 将显示此逻辑CPU所属的核心号。

echo“ 0”> / sys / devices / system / cpu / cpu3 / online 允许禁用逻辑cpu 3。

为什么有效?

我不知道确切的原因...但是系统通过关闭超线程(在我的i5笔记本电脑和具有60多个核的大型Xeon服务器上)变得更加敏感。我想这与每个cpu缓存,每个cpu内存分配,cpu调度程序分配以及进程优先级复杂迭代有关。我认为,使cpu调度程序知道如何使用它的复杂性会使超线程的好处远远超过。

对我来说,超线程的问题是:如果启动与逻辑内核一样多的cpu密集型线程,则将为cpu密集型任务提供快速的上下文切换,而为后台任务提供快速的上下文切换,因为超线程会完全消耗超线程。 CPU密集型任务。另一方面,如果启动与物理内核一样多的cpu密集型线程,则将没有上下文切换到那些任务,也没有用于上下文任务的快速上下文切换。看起来不错,但是后台任务将找到免费的逻辑处理器,并且几乎可以中介地运行。就像它们是实时性能(不错的-20)。

在第一种情况下,超线程是uselles,后台任务将使用昂贵的上下文切换,因为我在常规处理中最大限度地利用了超线程。第二个是无法接受的,因为我的CPU能力中有多达50%优先于后台任务。

我正在谈论的“ CPU密集型”任务是人工智能数据挖掘和授权服务器(我的工作)。廉价计算机和群集中的Blender渲染(以勾勒出我未来的房子)。

另外,这是猜测。

我的印象是更好,但事实并非如此。


我认为我的scriptlet比较容易理解。
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),或者如果使用grub,请编辑/boot/grub/menu.lst。


这在功能上等同于在BIOS中禁用HT吗?
ewwhite

我不确定这一点,但是是的,我希望noht等同于在BIOS上禁用它。
rems 2011年

2
这是一个Gentoo系统。我noht在grub内核命令行中尝试了该条目。系统不遵守该noht命令。与RHEL相同。请参阅:bugzilla.redhat.com/show_bug.cgi?
id=440321#c9

1
从至少Linux 2.6.18开始,这已经过时了。在noht取出内核选项。这是不幸的,因为只有在HT打开的情况下,Linux才启用某些Haswell性能计数器勘误表(BJ122,BV98,HSD29)的解决方法,并且这会在加载initramfs之前发生。
彼得·科德斯

9

您可以对每个内核使用“ thread_siblings_list”来关闭HT对中的第二个内核。

下面的命令管道是hacky的,不是经过优化的,因此希望通过这种方式使其更易于理解。

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

较新的内核提供了同时多线程(SMT)控件。

您可以使用以下命令检查SMT的状态:

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

更改状态

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

选项是;

  • 强制

我们已经使用Linux Kernel 4.4.0进行了测试


尼克,您好,欢迎访问该网站。有关测试(和版本)的信息非常有价值。
kubanczyk

极好,已在Ubuntu 16.04.6 LTS上进行了测试
Elder Geek

4

Lukas的回答很好,但是对于禁用HT并没有真正的作用,因为核心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

您的脚本是我的变体。为了确定,我们必须检查如果有多个CPU会发生什么情况。
Paul M

@PaulM这正是我测试并用于我的目的的地方:2插槽Haswell系统。
安东

0

我不得不等到可以参加国际劳工组织/德拉克。内核启动参数不适用于当前的Linux发行版。


0

在libsmbios-bin软件包(Debian,Ubuntu等)中,您具有二进制文件isCmosTokenActive和activateCmosToken。与令牌列表一起,您可以尝试执行以下操作:

# 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'

当然,它并没有像修补BIOS那样关闭超线程,基本上,它只是告诉内核任务调度程序不要使用某些内核,因为我们知道它们是伪内核。

基于运行时更改,基于先前状态/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,但这仍然不能为问题提供真正的答案。这些命令仅适用于特定的硬件配置,并且可能对其他硬件配置产生意想不到的影响。完全没有关于这些命令的作用的解释。
卡巴斯德

由于0表示关闭,而1表示打开,因此我很容易理解,第一个关闭了4个内核(在超线程打开的quandocore上伪造了8个内核),第二个关闭了它们。这些数字必须是{3,4}而不是{4..7}核心,如果您使用八位数,则必须是{8..15}
Zibri

0

旧话题,但是有理由尝试这个实验。首先,我完全不确定在运行时禁用(略微伪造的)CPU确实等同于在启动时禁用超线程。也就是说,我确实在我们的应用程序中看到了小的性能提升。(但不足以保留。)

使用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 

尝试命令W / O最终须藤SH核实无误。

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.