简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM