NUMA获取当前节点/核心

时间:2013-05-31 17:21:25

标签: c++ linux numa

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

3 个答案:

答案 0 :(得分:7)

我找到了这个解决方案:

#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);

答案 1 :(得分:5)

更轻量级的方法是使用RDTSCP指令(在支持它的x86系统上 - 它将被列为&#34; rdtscp&#34;在&#34; flags&#34;字段中的/ proc内/ cpuinfo)。

RDTSCP指令在一对32位寄存器(%eax和%ebx)中返回时间戳计数器值,但也返回%ecx寄存器中IA32_TSC_AUX MSR的内容。 IA32_TSC_AUX MSR的内容在理论上是任意的,但每个版本的Linux都能识别&#34; rdtscp&#34;处理器标志在每个逻辑处理器上预加载IA32_TSC_AUX寄存器,其编码为逻辑处理器编号(%ecx的位11:0)和&#34;节点编号&#34; (%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);;
}

答案 2 :(得分:4)

您需要使用getcpu()系统调用。正如man page所说:

  

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

所以,这应该符合你的目的。需要包含<linux/getcpu.h>,内核版本大于2.6.19,x86_64,i386 arch。