[英]CPU hot plugging and strict 1:1 threading
I wish to add support for CPU hot plugging in my application that has strict affinity rules. 我希望在具有严格相似性规则的应用程序中添加对CPU热插拔的支持。 Each physical core has exactly one thread pinned to it, but the logic I use for pinning a thread to a CPU is fairly naive and fails if a CPU between 0..N is offline.
每个物理核心都有一个固定的线程,但是我用于将线程固定到CPU的逻辑非常幼稚,如果0..N之间的CPU处于离线状态,则该逻辑将失败。
I have chosen an approach where I have an array of size MAX_CPU
, where each CPU on the system maps to a slot by its identifier. 我选择了一种方法,其中有一个大小为
MAX_CPU
的数组,其中系统上的每个CPU通过其标识符映射到一个插槽。 For example, CPU0 -> threads[0]
, and CPU1 -> threads[1]
, and so on. 例如,CPU0->
threads[0]
和CPU1-> threads[1]
,依此类推。 The idea is to mirror the system's setup. 这个想法是反映系统的设置。
for (i = 0; i < N; ++i)
set_affinity(threads[i], i);
However, if an offline CPU is encountered anywhere but the end, it will fail. 但是,如果在末尾以外的任何地方都遇到了离线CPU,则它将失败。
To make things worse, when a CPU is taken offline during runtime, the pinned thread's affinity mask is reset without notice. 更糟糕的是,当CPU在运行时脱机时,固定线程的亲和力掩码将重置,恕不另行通知。
Ultimately, I hope to support complex setups like: 最终,我希望支持复杂的设置,例如:
CPU0 CPU1 CPU2 CPU3
ONLINE OFFLINE ONLINE OFFLINE
How can I incorporate awareness of online and offline CPU:s into my application? 如何将对在线和离线CPU的了解纳入我的应用程序?
I'm avoiding /proc
and /sys
as I'm interested in porting to other platforms, specifically various BSD:s. 我避免使用
/proc
和/sys
因为我想移植到其他平台,特别是各种BSD:s。 I use x86_64 for now, so the cpuid
instruction may be useful. 我现在使用x86_64,因此
cpuid
指令可能有用。
Turns out sched_getaffinity(2)
is awesome and better suited for this case. 原来
sched_getaffinity(2)
非常棒,更适合这种情况。 The cpu_set_t
it fills in is not a generalized mask like 0xffffffff...
that would imply schedule anywhere, but actually a detailed and up-to-date mask of each online and permitted CPU. 它填充的
cpu_set_t
不是通用掩码,例如0xffffffff...
暗示要在任何地方进行调度,而是实际上是每个在线和允许使用的 CPU的详细且最新的掩码。 Using the CPU_*
macros, it's possible to extract how many CPU:s are online and which. 使用
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;
}
When notified of a hot plug event, a call to sched_getaffinity(2)
from a non-pinned thread will give us an updated mask. 当收到热插拔事件通知时,从非固定线程调用
sched_getaffinity(2)
将为我们提供更新的掩码。
An added benefit is awareness of utilities like taskset(1)
. 一个附加的好处是对诸如
taskset(1)
类的实用程序的taskset(1)
。
FreeBSD has a cpuset_getaffinity(2)
system call that probably operates in a similar fashion. FreeBSD有一个
cpuset_getaffinity(2)
系统调用,它可能以类似的方式运行。 I don't have access to try it out now. 我现在无权尝试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.