首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何跨内核同步TSC?

如何跨内核同步TSC?
EN

Stack Overflow用户
提问于 2012-05-07 23:20:17
回答 2查看 2.5K关注 0票数 4

使用:

代码语言:javascript
复制
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正在运行

代码语言:javascript
复制
while(globalIndex < COUNT)
{
  while(globalIndex %2 == 0 && globalIndex < COUNT)
    ;
  cycles[globalIndex][0] = rdtsc();
  cycles[globalIndex][1] = cpuToBindTo;
  __sync_add_and_fetch(&globalIndex,1);
}

线程2正在运行

代码语言:javascript
复制
while(globalIndex < COUNT)
{
  while(globalIndex %2 == 1 && globalIndex < COUNT)
    ;
  cycles[globalIndex][0] = rdtsc();
  cycles[globalIndex][1] = cpuToBindTo;
  __sync_add_and_fetch(&globalIndex,1);
}

我看到了

代码语言:javascript
复制
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标志是开的。

EN

回答 2

Stack Overflow用户

发布于 2012-05-08 11:18:30

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

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

如果你用正确的术语在谷歌上搜索,你会找到很多关于这个主题的资源,比如邮件列表讨论。例如,下面是one algorithm being discussed (尽管它显然不是一个好的)。然而,这不是userland开发人员应该担心的事情--这是一个只有内核开发人员才需要担心的神秘魔法。

基本上,它是操作系统的工作,在引导时,在一定的误差范围内,在SMP机器上的所有不同处理器和/或内核之间同步TSC计数器。如果你看到的数字如此离谱,那就是TSC同步出了问题,你的时间应该花在找出你的操作系统没有正确同步TSC的原因上,而不是尝试实现你自己的TSC同步算法。

票数 1
EN

Stack Overflow用户

发布于 2012-05-08 03:53:51

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

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10484640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档