4

使用:

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 标志已打开。

4

2 回答 2

1

你在什么上面运行这段代码?TSC 同步应该在操作系统/内核中完成,并且依赖于硬件。例如,您可以通过引导加载程序将类似标志传递powernow-k8.tscsync=1给内核引导参数。

您需要为您的操作系统和硬件组合搜索正确的 TSC 同步方法。总的来说,这整个过程是自动化的——如果您在自定义内核或非 i686 硬件上运行,我不会感到惊讶?

如果您使用正确的术语在 Google 上搜索,您会发现很多资源,例如关于此主题的邮件列表讨论。例如,这里有一个正在讨论的算法(尽管它显然不是一个好的算法)。然而,这不是用户级开发人员应该担心的事情——这是只有内核开发人员才需要担心的神秘魔法。

基本上,操作系统的工作是在启动时同步 SMP 机器上所有不同处理器和/或内核之间的 TSC 计数器,并在一定的误差范围内。如果您看到的数字非常偏离,则 TSC 同步存在问题,您最好花时间找出您的操作系统未正确同步 TSC 的原因,而不是尝试实施您自己的 TSC 同步算法。

于 2012-05-08T03:18:29.767 回答
0

您有 NUMA 内存架构吗?全局计数器可以位于 RAM 中,其中一个 CPU 距离几跳,另一个 CPU 位于本地。您可以通过将线程固定到同一 NUMA 节点上的核心来测试这一点。

编辑:我猜这是因为性能是特定于 CPU 的。

编辑:关于同步 TSC。我不知道一种简单的方法,这并不是说没有!如果您将核心 1 作为参考时钟,然后将其与核心 2 进行比较,会发生什么情况?如果您多次进行该比较并取最小值,您可能会得到一个很好的近似值。当您在比较过程中被抢占时,这应该可以处理这种情况。

于 2012-05-07T19:53:50.877 回答