【问题标题】:CPU hot plugging and strict 1:1 threadingCPU 热插拔和严格的 1:1 线程
【发布时间】:2012-08-21 13:31:23
【问题描述】:

我希望在我的具有严格关联规则的应用程序中添加对 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:s 的意识融入到我的应用程序中?

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

【问题讨论】:

  • "我正在避免使用 /proc 和 /sys,因为我有兴趣移植到其他平台" - 您目前如何访问 CPU 在线/离线状态?跨度>
  • @ArjunShankar 我无法访问每个 CPU 的状态,但在 Linux 上,我可以使用 sysconf(2) 获取在线和配置 CPU:s 的计数。现在,我只是乐观地在 CPU:s 0..N 中固定 N 个线程,并让它在离线 CPU:s 中失败。我正在寻找的是一种可靠的方法来强制每个在线 CPU 将一个线程固定到它上面。
  • 例如,我看不到在 FreeBSD 中对 CPU 热插拔的适当支持。我可能是错的,因为我找到的唯一相关结果是 from 2009, and it was in the negative
  • 另一方面,似乎有相当不错的关于 Linux 中 CPU 热插拔的文档。 Here is a 2005 announcement on ML/LWN 关于“新”文档。还有here is the document itself
  • 我的观点是,我认为你真的没有出路,只能以不可移植的方式编写这些东西。我从来没有尝试过,所以我可能是错的。我上面所说的一切都是搜索的结果(我这样做是因为我发现你的问题很有趣)。

标签: multithreading affinity hotplugging


【解决方案1】:

原来sched_getaffinity(2) 非常棒,更适合这种情况。它填写的cpu_set_t 不是像0xffffffff... 这样的通用掩码,它暗示任何地方的日程安排,而是每个在线允许 的详细且最新的掩码em> 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) 系统调用,它可能以类似的方式运行。我现在无权试用。

【讨论】:

    猜你喜欢
    • 2018-01-23
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 2014-02-19
    相关资源
    最近更新 更多