6

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

4

3 回答 3

9

一种更轻量级的方法是使用 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);;
}
于 2014-12-12T18:50:24.227 回答
9

我找到了这个解决方案:

#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);
于 2013-06-03T12:44:38.843 回答
4

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

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

因此,这应该符合您的目的。需要包含<linux/getcpu.h>,内核版本大于 2.6.19 和 x86_64,i386 架构。

于 2013-05-31T17:34:33.510 回答