任务集无法在 isolcpus 中的一系列内核上工作

use*_*126 15 kernel multi-threading cpu-usage scheduler affinity

作为序言,我在 AMD64 芯片组上使用带有内核 3.2 的 Debian Wheezy。我的机器有两个至强 E5-2690 内核。我设置了启动参数,以便一个 CPU 上的所有内核专用于单个进程。为此,我在 grub 中设置了 isolcpus=8,9,10,11,12,13,14,15。

到现在为止还挺好。现在假设我想对给定命令使用隔离的 CPU,简单地说,我将使用一个简单的无限循环:

$ taskset -c 8-15 bash -c 'while true ; 做回声你好>/dev/null; 完毕' &

到目前为止一切顺利,top 表明核心 8 的利用率接近 100%。现在假设我再次启动该命令:

$ taskset -c 8-15 bash -c 'while true ; 做回声你好>/dev/null; 完毕' &

现在 top 显示内核 9-15 保持空闲并且两个进程共享内核 8。如果相反,我这样做:

$ taskset -c 8 bash -c 'while true ; 做回声你好>/dev/null; 完毕' &

$ taskset -c 9 bash -c 'while true ; 做回声你好>/dev/null; 完毕' &

核心 8 和 9 各获得 100% 的利用率。这仅适用于 isolcpus,因为具有内核 1-7 的相同任务集正确地将进程分布在相关内核上。此外,“taskset -p”表明 8-15 个进程的关联掩码设置正确。内核调度程序似乎拒绝使用除 isolcpus 关联掩码上指定的最低内核之外的任何内容。

现在通常这对我上面的例子来说没什么大不了的,只需为每个进程指定单独的内核。但是我想在专用 CPU 上运行高度多线程的应用程序。我想指定核心集并让线程池自动使用,而不必为产生的每个线程单独重置处理器关联。

有谁知道如何让调度程序从 isolcpu 集中给我一个以上的核心?

use*_*126 12

经过一天的沮丧,我确定了一个解决方案。此行为似乎是默认内核调度程序算法(此发行版/内核的 SCHED_OTHER)的产物。将进程更改为不同的算法可以消除该问题,在进程/线程之间充分利用了 isolcpus。

我最终使用了 SCHED_RR,但我也测试了 SCHED_FIFO 和 SCHED_IDLE,这两个似乎都有效。可以使用 chrt 实用程序使用替代算法启动该进程:

$ sudo chrt -r 1 [命令]

(如果您想以非 root 身份运行,您可以使用 setcap 实用程序在与命令相关的二进制文件上启用 CAP_SYS_NICE)