Я использую libnuma на Linux. Мои потоки должны знать узел / ядро, на котором они работают. Можно ли как-то получить узел / ядро текущих потоков? Я просмотрел документацию, но не нашел такой функции …
Я нашел это решение:
#include <stdio.h>
#include <utmpx.h>
int main(void) {
printf("CPU: %d\n", sched_getcpu());
return 0;
}
Затем, если вам нужен узел процессора, вы можете использовать numa.h:
int cpu = sched_getcpu();
int node = numa_node_of_cpu(cpu);
Более легкий подход состоит в том, чтобы использовать инструкцию RDTSCP (в системах x86, которые ее поддерживают, она будет указана как «rdtscp» в поле «flags» / proc / cpuinfo).
Инструкция RDTSCP возвращает значение счетчика меток времени в паре 32-битных регистров (% eax и% ebx), но также возвращает содержимое MSR IA32_TSC_AUX в регистре% ecx. Содержимое MSR IA32_TSC_AUX теоретически произвольно, но каждая версия Linux, которая распознает флаг процессора «rdtscp», предварительно загружает регистр IA32_TSC_AUX на каждый логический процессор с кодировкой обоих номеров логического процессора (биты 11: 0% ecx ) и «номер узла» (биты 21:12% ecx). Инструкция захватывает регистры 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);;
}
Вам нужно использовать getcpu()
системный вызов. Как говорится на странице руководства:
определить процессор и узел NUMA, на котором запущен вызывающий поток
Итак, это должно служить вашей цели. Необходимо включить <linux/getcpu.h>
, с версией ядра больше 2.6.19 и для x86_64, i386 arch.