如何禁用一个 CPU

Yve*_*ves 9 linux cpu ps numa cpu-usage

我正在尝试禁用服务器的某些 CPU。
我找到了这个链接:https : //www.cyberciti.biz/faq/debian-rhel-centos-redhat-suse-hotplug-cpu/linux-turn-on-off-cpu-core-commands/,它提供我的方法如下:

这是numactl --hardware给我的:
在此处输入图片说明

我想禁用从 16 到 63 的所有 CPU,所以我编写了一个名为opCPUs.sh如下的脚本:

#!/bin/bash

for i in {16..63}; do
    if [[ "$1" == "enable" ]]; then
        echo 1 > /sys/devices/system/cpu/cpu$i/online
    elif [[ "$1" == "disable" ]]; then
        echo 0 > /sys/devices/system/cpu/cpu$i/online
    else
        echo 'illegal parameter'
    fi
done
grep "processor" /proc/cpuinfo
Run Code Online (Sandbox Code Playgroud)

然后我执行它:./opCPUs.sh disable我可以grep在脚本中看到结果:
在此处输入图片说明

它似乎工作。

现在我认为所有进程都应该在 CPU 0 - 15 中,因为其他进程已被禁用。
所以我使用现有的流程dbus来验证如下:
ps -Lo psr $(pgrep dbus)

我明白了:
在此处输入图片说明

psr告诉我在哪个CPU的进程正在运行,对不对?如果是这样,我已经禁用了 CPU 60、CPU 52 等,为什么它们还在这里?

Yve*_*ves 6

经过一些测试,我得到了如下结果:

echo 0 > /sys/devices/system/cpu/cpu4/online
Run Code Online (Sandbox Code Playgroud)

确实禁用了第 4 个 CPU。

“禁用第 4 个 CPU”意味着以后的进程将不再分配给第 4 个 CPU。换句话说,在“禁用第 4 个 CPU”之前位于第 4 个 CPU 的进程不会在禁用 CPU 时从 CPU 中移出。

说我有四个 CPU:0、1、2 和 3。所以我可以:

echo 0 > /sys/devices/system/cpu/cpu1/online
echo 0 > /sys/devices/system/cpu/cpu2/online
echo 0 > /sys/devices/system/cpu/cpu3/online
./MyShell.sh
Run Code Online (Sandbox Code Playgroud)

强制./MyShell.sh将 分配给 CPU0。

顺便说一下,重启将自动启用所有 CPU。


Rui*_*iro 6

除了@Yves 的回答,您实际上还可以使用isolcpus内核参数。

要使用 Debian 或 Ubuntu 禁用第 4 个 CPU/核心 (CPU 3):

/etc/default/grub添加isolcpus=3GRUB_CMDLINE_LINUX_DEFAULT

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash isolcpus=3"
Run Code Online (Sandbox Code Playgroud)

sudo update-grub
Run Code Online (Sandbox Code Playgroud)

重新启动服务器。

isolcpus — 将 CPU 与内核调度程序隔离。

概要 isolcpus= cpu_number [, cpu_number ,...]

说明 从通用内核 SMP 平衡和调度程序算法中删除由 cpu_number 值定义的指定 CPU。将进程移入或移出“独立”CPU 的唯一方法是通过 CPU 关联系统调用。cpu_number 从 0 开始,因此最大值比系统上的 CPU 数量少 1。

此选项是隔离 CPU 的首选方法。另一种方法是手动设置系统中所有任务的 CPU 掩码,可能会导致问题和次优的负载平衡器性能。

有趣的是,使用此内核参数可以留出一个 CPU,以便稍后使用 CPU 与一个进程的亲和性/将进程固定到 CPU,从而确保在该 CPU 上不再有用户进程运行。

此外,还可以使服务器更加稳定,并保证具有非常高负载的特定进程将拥有自己的 CPU 来运行。在意识到这种设置之前,我已经看到 Meru 使用他们基于 Linux 的控制器这样做。

然后将进程分配给第四个 CPU (CPU 3) 的相关命令是:

sudo taskset -cp PID
Run Code Online (Sandbox Code Playgroud)

taskset用于设置或检索给定 PID 的运行进程的 CPU 亲和性,或使用给定的 CPU 亲和性启动新的 COMMAND。CPU 亲和性是一个调度程序属性,它将进程“绑定”到系统上的一组给定 CPU。Linux 调度程序将遵守给定的 CPU 关联性,并且该进程不会在任何其他 CPU 上运行。请注意,Linux 调度程序还支持自然 CPU 亲和性:出于性能原因,调度程序尽可能将进程保持在同一 CPU 上。因此,强制特定的 CPU 关联仅在某些应用程序中有用。


概括

有几种技术适用于这个问题:

isolcpus = 4在 grub 中设置并重新启动可以永久禁用用户土地进程的第 5 个 CPU/CPU 4;

echo 0 > /sys/devices/system/cpu/cpu4/online 禁用第 5 个 CPU/CPU 4,它仍将继续为已分配给它的进程工作,但不会再将新进程分配给 CPU 4;

taskset -c 3 ./MyShell.sh将强制MyShell.sh分配给第 4 个 CPU/CPU 3 而第 4 个 CPU 仍然可以接受其他用户土地进程,如果 isolcpus 不排除它这样做。

附注。有趣的是,我在现场使用isolcpus/ 的最好例子是taskset一个非常繁忙的站点的 SSL 前端,它每隔几周ssh就会变得不稳定,Ansible/不再让我远程进入。

我应用了上面讨论的技术,从那以后它一直以非常稳定的方式工作。