首先,我在 AMD64 芯片组上使用内核为 3.2 的 Debian Wheezy。我的机器有两个 Xeon E5-2690 核心。我设置了启动参数,以便一个 CPU 上的所有核心都专用于单个进程。为此,我在 grub 中设置了 isolcpus=8,9,10,11,12,13,14,15。
到目前为止一切顺利。现在假设我想对给定的命令使用隔离的 CPU,为了简单起见,我将使用一个简单的无限循环:
$ taskset -c 8-15 bash -c 'while true ; do echo hello >/dev/null; done' &
到目前为止一切顺利,top 显示核心 8 的利用率已接近 100%。现在假设我再次启动该命令:
$ taskset -c 8-15 bash -c 'while true ; do echo hello >/dev/null; done' &
现在 top 显示核心 9-15 保持空闲,并且两个进程共享核心 8。如果我这样做:
$ taskset -c 8 bash -c 'while true ; do echo hello >/dev/null; done' &
$ taskset -c 9 bash -c 'while true ; do echo hello >/dev/null; done' &
核心 8 和 9 均按应有的方式获得 100% 的利用率。这仅适用于 isolcpus,因为具有核心 1-7 的相同任务集正确地将进程分布在相关核心上。此外,“taskset -p”显示 8-15 进程的关联掩码设置正确。看来内核调度程序拒绝使用 isolcpus 关联掩码上指定的最低核心以外的任何核心。
现在,通常对于我上面的示例来说,这不会有什么大问题,只需为每个进程指定单独的核心即可。但是我想在专用 CPU 上运行高度多线程的应用程序。我想指定核心集并让线程池自动使用,而不必为生成的每个线程单独重置处理器亲和性。
有人知道如何让调度程序从 isolcpu 集中给我一个以上的核心吗?
答案1
经过一天的挫折,我终于找到了解决方案。此行为似乎是默认内核调度程序算法(此发行版/内核的 SCHED_OTHER)的产物。将进程更改为其他算法可消除此问题,isolcpus 可在进程/线程间得到充分利用。
我最终使用了 SCHED_RR,但我也测试了 SCHED_FIFO 和 SCHED_IDLE,它们似乎都可以工作。可以使用 chrt 实用程序使用替代算法启动该进程:
$ sudo chrt -r 1 [命令]
(如果您想以非 root 身份运行,您可以使用 setcap 实用程序在与该命令相关的二进制文件上启用 CAP_SYS_NICE)