使用:
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标志已打开。
答案 0 :(得分:1)
您在运行此代码的是什么? TSC同步应该在OS /内核中完成,并且取决于硬件。例如,您可以通过引导加载程序将powernow-k8.tscsync=1
之类的标志传递给内核引导参数。
您需要为OS和硬件的组合搜索正确的TSC同步方法。总的来说,这一切都是自动化的 - 如果您在自定义内核或非i686硬件上运行,我不会感到惊讶吗?
如果您使用正确的字词在Google上搜索,您会发现很多资源,例如有关此主题的邮件列表讨论。例如,这里是one algorithm being discussed(虽然显然它不是一个好的)。然而,这并不是用户开发人员应该担心的事情 - 这是一个神秘的巫术,只有内核开发者需要担心他们的头脑。
基本上,在启动时,操作系统的工作是在一定的误差范围内同步SMP机器上所有不同处理器和/或内核之间的TSC计数器。如果您看到的数据非常严重,那么TSC同步就会出现问题,您可以更好地花时间查找操作系统未正确同步TSC的原因,而不是尝试实施自己的TSC同步算法。 / p>
答案 1 :(得分:0)
你有NUMA内存架构吗?全局计数器可以位于RAM中,对于其中一个CPU而言是一个跳远,而对于另一个CPU则是本地的。您可以通过将线程修复到同一NUMA节点上的核心来测试这一点。
编辑:我猜这是因为性能是CPU特定的。编辑:关于同步TSC。我不知道一个简单的方法,这并不是说没有一个!如果将核心1作为参考时钟,然后将其与核心2进行比较,会发生什么?如果您多次进行该比较并采取最小值,则可能会有一个很好的近似值。这应该处理在比较过程中被抢占的情况。