CPU 亲和性如何与 Linux 中的 cgroups 交互?

CPU 亲和性如何与 Linux 中的 cgroups 交互?

我正在尝试在一组独立的 CPU 上运行多线程基准测试。长话短说,我最初尝试使用isolcpustaskset,但遇到了问题。现在我正在玩 cgroups/csets。

我认为“简单”cset shield用例应该可以很好地工作。我有 4 个核心,所以我想使用核心 1-3 进行基准测试(我还将这些核心配置为自适应刻度模式),然后核心 0 可以用于其他所有操作。

按照教程这里,它应该简单如下:

$ sudo cset shield -c 1-3
cset: --> shielding modified with:
cset: "system" cpuset of CPUSPEC(0) with 105 tasks running
cset: "user" cpuset of CPUSPEC(1-3) with 0 tasks running

所以现在我们有一个隔离的“盾牌”(用户 cset),而核心 0 用于其他一切(系统 cset)。

好的,到目前为止看起来不错。现在让我们看看htop。所有进程都应该已迁移到 CPU 0 上:

定义集

嗯?有些进程显示为在屏蔽核心上运行。为了排除 htop 有错误的情况,我还尝试使用它taskset来检查显示为在屏蔽中的进程的亲和性掩码。

也许那些任务是无法移动的?让我们挑选一个显示在 CPU3 上运行的任意进程(应该在屏蔽中),htop并根据以下内容查看它是否出现在系统 cgroup 中cset

$ cset shield -u -v | grep 864
   root       864     1 Soth [gmain]
   vext01    2412  2274 Soth grep 864 

是的,根据 ,它正在系统 cgroup 上运行cset。所以htopcset同意。

那么这里发生了什么?我该相信谁:CPU 亲和性 ( htop/ taskset) 还是cset?

我怀疑你不应该cset同时使用和亲和力。也许护盾工作正常,我应该忽略亲和力掩码和htop输出。无论如何,我觉得这很令人困惑。有人能解释一下吗?

答案1

来自cpusets 文档

对 sched_setaffinity 的调用仅被过滤到该任务的 cpuset 中允许的 CPU。

这意味着 CPU 亲和性掩码与该进程所属的 cgroup 中的 CPU 相交。

例如,如果某个进程的亲和性掩码包括核心 {0, 1, 3},并且该进程在系统 cgroup 上运行,而该系统 cgroup 限制为核心 {1, 2},那么该进程将被强制在核心 1 上运行。

我 99% 确信htop输出是“错误的”,因为自创建 cgroups 以来,进程从未被唤醒过,并且显示屏显示最后的进程运行的核心。

如果我在制作防护罩之前启动 vim,vim 会分叉两次(出于某种原因),并且最深的子进程在核心 2 上运行。如果我制作防护罩,然后让 vim 进入睡眠状态(ctrl+z)并唤醒它,那么两个进程都会移动到核心 0。我认为这证实了htop显示陈旧信息的假设。

您还可以检查/proc/<pid>/status并查看cpus_allowed_*字段。

例如,这里有一个console-kit-daemon进程(pid 857),在 htop 中显示为在核心 3 上运行,但是/proc/857/status

Cpus_allowed:   1
Cpus_allowed_list:      0

我认为这说明亲和力掩码为 0x1,由于 cgroups,它仅允许在核心 1 上运行:即 intersect({0,1,2,3}, {0}) = {0}。

如果可以的话,我会暂时搁置这个问题,看看是否能找到更好的答案。

感谢@davmac 对此提供的帮助(在 irc 上)。

相关内容