Использование:Как синхронизировать TSC по ядрам?
inline uint64_t rdtsc()
{
uint32_t cycles_high;
uint32_t cycles_low;
asm volatile ("CPUID\n\t"
"RDTSC\n\t"
"mov %%edx, %0\n\t"
"mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low)::
"%rax", "%rbx", "%rcx", "%rdx");
return (((uint64_t)cycles_high << 32) | cycles_low);
}
нить 1 погонный
while(globalIndex < COUNT)
{
while(globalIndex %2 == 0 && globalIndex < COUNT)
;
cycles[globalIndex][0] = rdtsc();
cycles[globalIndex][1] = cpuToBindTo;
__sync_add_and_fetch(&globalIndex,1);
}
нить 2 работает
while(globalIndex < COUNT)
{
while(globalIndex %2 == 1 && globalIndex < COUNT)
;
cycles[globalIndex][0] = rdtsc();
cycles[globalIndex][1] = cpuToBindTo;
__sync_add_and_fetch(&globalIndex,1);
}
я вижу
CPU rdtsc() t1-t0
11 = 5023231563212740 990
03 = 5023231563213730 310
11 = 5023231563214040 990
03 = 5023231563215030 310
11 = 5023231563215340 990
03 = 5023231563216330 310
11 = 5023231563216640 990
03 = 5023231563217630 310
11 = 5023231563217940 990
03 = 5023231563218930 310
11 = 5023231563219240 990
03 = 5023231563220230 310
11 = 5023231563220540 990
03 = 5023231563221530 310
11 = 5023231563221840 990
03 = 5023231563222830 310
11 = 5023231563223140 990
03 = 5023231563224130 310
11 = 5023231563224440 990
03 = 5023231563225430 310
11 = 5023231563225740 990
03 = 5023231561739842 310
11 = 5023231561740152 990
03 = 5023231561741142 310
11 = 5023231561741452 12458
03 = 5023231561753910 458
11 = 5023231561754368 1154
03 = 5023231561755522 318
11 = 5023231561755840 982
03 = 5023231561756822 310
11 = 5023231561757132 990
03 = 5023231561758122 310
11 = 5023231561758432 990
03 = 5023231561759422 310
Я не знаю, как я получил понг 12458, но было интересно, почему я видел 310-990-310 вместо 650-650-650. Я думал, что tsc должен быть синхронизирован по всем ядрам. мой флаг constant_tsc cpu включен.
Я запускаю это на сервере с 2 гнездами, используя cpus 3 и 11, которые находятся на сокете 2. lscpu | grep NUMA возвращает ' NUMA node0 CPU (s): 0,2,4,6,8,10 NUMA node1 CPU (s): 1,3,5,7,9,11 ' – fission
Только для ада из этого ... что происходит, когда вы запускаете потоки на разных ЦП, отличных от 3 и 11? – johnnycrash
Является ли globalindex неустойчивым? Хотя, для глобалов, летучесть, вероятно, не требуется. Вы компилируете с -O3? Кроме того, чтобы получить более чистую статистику, мы можем суммировать статистику в массивах, которые не загрязняют строки кэша для другого потока. Используйте struct для хранения процессора/времени, а затем добавьте пару фиктивных полей, чтобы он добавлял до 64 байтов. Затем объявите циклы с __attribute ((align (64)).После этого каждое обновление должно быть в чистой чистой строке кэша. – johnnycrash