我希望在我的应用程序中添加对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
指令可能很有用。
答案 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)
系统调用,可能以类似的方式运行。我现在无权试用。