CPU热插拔和严格的1:1线程

时间:2012-08-21 13:31:23

标签: multithreading affinity hotplugging

我希望在我的应用程序中添加对CPU热插拔的支持,该应用程序具有严格的关联性规则。每个物理内核只有一个固定的线程,但我用来将线程固定到CPU的逻辑非常幼稚,如果0..N之间的CPU处于脱机状态则会失败。

我选择了一种方法,我有一个大小为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的意识纳入我的应用程序?

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

1 个答案:

答案 0 :(得分:0)

结果sched_getaffinity(2)很棒,更适合这种情况。它填写的cpu_set_t不是像0xffffffff...这样的通用掩码,它意味着在任何地方安排,但实际上是每个在线允许 CPU。使用CPU_*宏,可以提取有多少CPU在线以及哪些。

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)系统调用,可能以类似的方式运行。我现在无权试用。