我在 Linux 上使用 libnuma。我的线程应该知道它们正在运行的节点/核心。是否有可能以某种方式获取当前线程的节点/核心?我已经通过文档,但我没有找到这样的功能......
3 回答
一种更轻量级的方法是使用 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);;
}
我找到了这个解决方案:
#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);
您需要使用getcpu()
系统调用。正如手册页所说:
确定运行调用线程的 CPU 和 NUMA 节点
因此,这应该符合您的目的。需要包含<linux/getcpu.h>
,内核版本大于 2.6.19 和 x86_64,i386 架构。