【问题标题】:Can I programmatically pick and choose which core of a multi-core CPU my thread should run on?我可以以编程方式选择我的线程应该在多核 CPU 的哪个核心上运行吗?
【发布时间】:2010-12-23 16:57:04
【问题描述】:

还是受操作系统控制?我听说 Google 的新 Go 语言有内置功能,可以让程序员做到如此精细,还是我理解错了?

【问题讨论】:

  • 这可能是可能的,但您为什么要这样做?通常,操作系统可以比用户空间应用程序更好地决定在哪个 CPU 上执行代码。
  • @Zach 如果您可以很好地控制每个 CPU 的功能,某些算法确实会运行得更好。例如,如果一个线程被抢占,带有自己滚动自旋锁的算法会做得很差,所以最好在每个线程中绑定到一个特定的核心。或者我可以想象它与非常受 CPU 限制的东西相关。那就是说……你说得对,那是一种小众的东西。
  • @asveikau 当然,但是您运行的 CPU 不会影响您是否会被抢占。我能想到的一种情况是在 NUMA 架构中。但我怀疑用户空间程序能否做出比随机选择更有益的决定。
  • @Zach 想象两个线程被分配给同一个内核,即使另一个线程空闲运行也不是那么不合理。通过设置亲和力,您可以更明确地避免这种情况。

标签: linux


【解决方案1】:

对于 linux 操作系统,sched_setaffinity 是您的答案。从 linux kernel 2.5.8 开始支持。

名字

sched_setaffinity, sched_getaffinity — 设置和获取进程的 CPU 关联掩码

#define _GNU_SOURCE
#include <sched.h>

int sched_setaffinity(  pid_t pid,
    size_t cpusetsize,
    cpu_set_t *mask);

int sched_getaffinity(  pid_t pid,
    size_t cpusetsize,
    cpu_set_t *mask);

亲和力掩码实际上是一个 每个线程的属性可以是 独立调整每个 线程组中的线程。价值 从 gettid(2) 调用返回的可以 在参数 pid 中传递。 将 pid 指定为 0 将设置 调用线程的属性,以及 传递调用返回的值 to getpid(2) 将设置属性 对于线程的主线程 团体。 (如果您使用的是 POSIX 线程 API,然后使用 pthread_setaffinity_np(3) 而不是 sched_setaffinity().)

【讨论】:

    【解决方案2】:

    由操作系统决定。

    您可以使用pthread_attr_setaffinity_np()为其设置提示。

    但是操作系统可以覆盖你。上面的调用只是您的程序向操作系统提出的建议。

    至于 Go,我还没有使用过它,甚至没有深入研究过它,但我对 Go 的理解是,很多并行性是相当隐含的。你有协同例程(他们说“go-routines”,非常双关语)和它们之间的通信。看起来 CPU 亲和性和线程本身的概念是分开的。也就是说,如果语言运行时认为这是最好的,它甚至可以决定在 1 个 CPU 上完成这一切......但我再次提醒我,我没有深入研究它,所以我可能是错的。 :-)

    【讨论】:

      【解决方案3】:

      答案是肯定的,您可以通过编程方式选择进程在哪个内核上运行。正如 arsane 所提到的,答案在于 sched_set_affinity(),然后是 pthread_setaffinity_np() 用于 pthread。

      这里有一个nifty tutorial,关于如何使用进程执行此操作(来自对this 问题的回答。)

      基本上,这是使用位掩码完成的。这意味着有一个整数(比如 32 位),如果第一位 == 1,则允许该进程在处理器 1 上运行。如果第二位 == 1,则允许该进程在处理器 1 上运行处理器 2. 等

      所以默认情况下,亲和位掩码 = 1...111(32 次)。这意味着“进程可能在处理器 1、2、3、...、32 上运行。”当然,如果你只有 2 个核心,那么额外的 30 位将不适用。

      但是,如果您将该位掩码设置为:0...010,则仅允许“处理器 2”执行该进程。

      这也解释了为什么 linux 支持的处理器 maximum number 是 32。(开箱即用,无需调整,x86,在许多常见硬件上,无需集群等)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-12
        • 2016-08-16
        相关资源
        最近更新 更多