【问题标题】:NUMA Get Current Node/CoreNUMA 获取当前节点/核心
【发布时间】:2013-05-27 14:09:30
【问题描述】:

我在 Linux 上使用 libnuma。我的线程应该知道它们正在运行的节点/核心。是否有可能以某种方式获取当前线程的节点/核心?查了文档,没找到这样的功能……

【问题讨论】:

    标签: c++ linux numa


    【解决方案1】:

    我找到了这个解决方案:

    #include <stdio.h>
    #include <utmpx.h>
    
    int main(void) {
      printf("CPU: %d\n", sched_getcpu());
      return 0;
    }
    

    然后,如果需要cpu的节点,可以使用numa.h:

    int cpu = sched_getcpu();
    int node = numa_node_of_cpu(cpu);
    

    【讨论】:

    • sched_getcpu() 是最稳定的获取 cpuid 的方法。因为,您明确地寻找 cpu 和节点 id,这就是我使用 getcpu() 回复的原因。实际上,getcpu() 没有 libc 包装器,您需要使用 syscalls() 系统调用。而且,这是 sched_getcpu() 优于 getcpu() 的另一个原因,以及可移植性问题。
    【解决方案2】:

    一种更轻量级的方法是使用 RDTSCP 指令(在支持它的 x86 系统上,它将在 /proc/cpuinfo 的“flags”字段中列为“rdtscp”)。

    RDTSCP 指令在一对 32 位寄存器(%eax 和 %ebx)中返回时间戳计数器值,但也返回 %ecx 寄存器中 IA32_TSC_AUX MSR 的内容。 IA32_TSC_AUX MSR 的内容在理论上是任意的,但识别“rdtscp”处理器标志的每个 Linux 版本都会在每个逻辑处理器上预加载 IA32_TSC_AUX 寄存器,并使用逻辑处理器编号(%ecx 的位 11:0 ) 和“节点号”(%ecx 的第 21:12 位)。该指令以原子方式抓取 TSC 和 IA32_TSC_AUX 寄存器,因此可以保证 TSC 值和 IA32_TSC_AUX 值是在同一个内核上获得的(如果 TSC 在不同内核上具有不同的偏移量,这一点至关重要)。

    这种方法的好处是 RDTSCP 是用户空间机器语言指令,因此您不需要与内核或任何库进行交互。在最近的系统上,开销低于 50 个周期。我使用的套路是:

    unsigned long tacc_rdtscp(int *chip, int *core)
    {
        unsigned long a,d,c;
        __asm__ volatile("rdtscp" : "=a" (a), "=d" (d), "=c" (c));
        *chip = (c & 0xFFF000)>>12;
        *core = c & 0xFFF;
        return ((unsigned long)a) | (((unsigned long)d) << 32);;
    }
    

    【讨论】:

      【解决方案3】:

      您需要使用getcpu() 系统调用。正如手册页所说:

      确定运行调用线程的 CPU 和 NUMA 节点

      所以,这应该符合您的目的。需要包含&lt;linux/getcpu.h&gt;,内核版本大于2.6.19,对于x86_64,i386 arch。

      【讨论】:

      • 谢谢,这应该可以,但我没有设法运行它。没有 ,文档说它应该直接用 syscall() 调用。所以我用 和 sched_getcpu()... 尝试了另一个解决方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      • 2011-01-03
      相关资源
      最近更新 更多