1

我希望在具有严格关联规则的应用程序中添加对 CPU 热插拔的支持。每个物理核心都固定有一个线程,但我用于将线程固定到 CPU 的逻辑相当幼稚,如果 0..N 之间的 CPU 离线,则会失败。

我选择了一种方法,其中我有一个 size 数组,MAX_CPU系统上的每个 CPU 通过其标识符映射到一个插槽。例如,CPU0 ->threads[0]和 CPU1 ->threads[1]等等。这个想法是反映系统的设置。

for (i = 0; i < N; ++i)
    set_affinity(threads[i], i);

但是,如果在任何地方遇到离线 CPU,它就会失败。

更糟糕的是,当 CPU 在运行时脱机时,固定线程的关联掩码会在没有通知的情况下重置。

最终,我希望支持复杂的设置,例如:

CPU0     CPU1      CPU2     CPU3
ONLINE   OFFLINE   ONLINE   OFFLINE

如何将在线和离线 CPU:s 的意识整合到我的应用程序中?

我正在避免/proc并且/sys因为我有兴趣移植到其他平台,特别是各种 BSD:s。我现在使用 x86_64,所以该cpuid指令可能有用。

4

1 回答 1

0

事实证明sched_getaffinity(2)它很棒,更适合这种情况。cpu_set_t它所填写的不是一个通用的掩码,0xffffffff...它意味着任何地方的调度,而是每个在线允许的CPU 的详细且最新的掩码。使用CPU_*宏,可以提取有多少 CPU:s 在线以及哪些。

cpu_set_t set;
int i, n;

if (sched_getaffinity(0, sizeof(cpu_set_t), &set))
    return;

n = CPU_COUNT(&set);

/* pin a thread to each online and permitted cpu */
for (i = 0; n; ++i)
    if (CPU_ISSET(i, &set)) {
        /* spawn a thread and pin it to cpu identified by 'i' ... */
        --n;
    }

当通知热插拔事件时,sched_getaffinity(2)来自非固定线程的调用将为我们提供更新的掩码。

另一个好处是对实用程序的认识,例如taskset(1).

FreeBSD 有一个cpuset_getaffinity(2)可能以类似方式运行的系统调用。我现在无权试用。

于 2012-08-23T08:54:07.040 回答