我有一个在远程设施上运行金融交易应用程序的系统。我无权访问ILO / DRAC,但需要禁用超线程。该系统运行Intel Westmere 3.33GHz X5680六核CPU。我可以重新启动,但要确保由于性能问题而导致系统未启用超线程。有没有从Linux内部执行此操作的干净方法?
编辑:noht
添加到内核引导命令行的指令不起作用。与RHEL相同。
请参阅:https: //bugzilla.redhat.com/show_bug.cgi?id = 440321#c9
我有一个在远程设施上运行金融交易应用程序的系统。我无权访问ILO / DRAC,但需要禁用超线程。该系统运行Intel Westmere 3.33GHz X5680六核CPU。我可以重新启动,但要确保由于性能问题而导致系统未启用超线程。有没有从Linux内部执行此操作的干净方法?
编辑:noht
添加到内核引导命令行的指令不起作用。与RHEL相同。
请参阅:https: //bugzilla.redhat.com/show_bug.cgi?id = 440321#c9
Answers:
您可以根据需要在运行时执行此操作。我在这里找到了一个不错的解决方案: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
您可以设置自己的脚本,以在系统启动后立即运行。
echo 1
而不是echo 0
应该重新打开它们。
要禁用超线程,我在/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渲染(以勾勒出我未来的房子)。
另外,这是猜测。
我的印象是更好,但事实并非如此。
对于非常老的内核(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。
您可以对每个内核使用“ 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
较新的内核提供了同时多线程(SMT)控件。
您可以使用以下命令检查SMT的状态:
cat /sys/devices/system/cpu/smt/active
更改状态
echo off > /sys/devices/system/cpu/smt/control
选项是;
我们已经使用Linux Kernel 4.4.0进行了测试
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
在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
现在,最大的问题是您是否仅需要重新启动即可生效,或者是否需要重新启动电源。尝试一下,看看效果如何!
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
在这种情况下很容易失败。
禁用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
,但这仍然不能为问题提供真正的答案。这些命令仅适用于特定的硬件配置,并且可能对其他硬件配置产生意想不到的影响。完全没有关于这些命令的作用的解释。
旧话题,但是有理由尝试这个实验。首先,我完全不确定在运行时禁用(略微伪造的)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核实无误。
sysbench --num-threads=1 --test=cpu run
具有不同数量的线程并打开和关闭HT的情况表示,当有多个线程时,禁用HT会降低性能,即使只有一个线程,关闭HT也无济于事。因此,我建议保留原样:这是最佳选择。