使用:
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的pong的,但我想知道为什么我看到的是310990310而不是650650。我认为tsc应该是跨内核同步的。我的constant_tsc cpu标志是开的。
发布于 2012-05-08 11:18:30
您是在什么上运行这段代码的?TSC同步应该在操作系统/内核中完成,并且依赖于硬件。例如,您可以通过引导加载程序将一个类似powernow-k8.tscsync=1的标志传递给内核引导参数。
您需要为您的操作系统和硬件组合搜索正确的TSC同步方法。总的来说,整个过程都是自动化的--如果您运行在自定义内核或非i686硬件上,我不会感到惊讶。
如果你用正确的术语在谷歌上搜索,你会找到很多关于这个主题的资源,比如邮件列表讨论。例如,下面是one algorithm being discussed (尽管它显然不是一个好的)。然而,这不是userland开发人员应该担心的事情--这是一个只有内核开发人员才需要担心的神秘魔法。
基本上,它是操作系统的工作,在引导时,在一定的误差范围内,在SMP机器上的所有不同处理器和/或内核之间同步TSC计数器。如果你看到的数字如此离谱,那就是TSC同步出了问题,你的时间应该花在找出你的操作系统没有正确同步TSC的原因上,而不是尝试实现你自己的TSC同步算法。
发布于 2012-05-08 03:53:51
你有NUMA内存架构吗?全局计数器可以位于RAM中,其中一个CPU只有几个跳跃,而另一个CPU在本地。您可以通过将线程固定到同一NUMA节点上的核心来测试这一点。
编辑:我猜这是因为性能是特定于CPU的。
EDIT:关于同步TSC。我没有意识到一个简单的方法,这并不是说没有一个方法!如果您将内核1作为参考时钟,然后将其与内核2进行比较,会发生什么情况?如果你做了多次比较,取最小值,你可能会有一个很好的近似值。这应该可以处理在比较过程中被抢占的情况。
https://stackoverflow.com/questions/10484640
复制相似问题