我在Linux上使用libnuma。 我的线程应该知道他们正在运行的节点/核心。 是否有可能以某种方式获取当前线程的节点/内核? 我已经通过文档,但我没有find这样的function…
我发现这个解决方案:
#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()
系统调用。 正如man page所说:
确定调用线程正在运行的CPU和NUMA节点
所以,这应该是你的目的。 需要包含<linux/getcpu.h>
,内核版本大于2.6.19,x86_64,i386 arch。
较轻的方法是使用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);; }