为什么RDTSC不是序列化指令?

时间:2012-08-22 02:45:27

标签: performance x86 x86-64 cpu-architecture cpu-cycles

Intel manuals for the RDTSC instruction警告当RDTSC实际执行时乱序执行可能会改变,所以他们建议在它前面插入一个CPUID指令,因为CPUID会序列化指令流(CPUID永远不会乱序执行) 。我的问题很简单:如果他们有能力进行序列化指令,他们为什么不进行RDTSC序列化?它的全部要点似乎是获得周期精确的时间。是否存在希望在序列化指令之前的情况?

较新的Intel CPU有一个单独的RDTSCP指令正在序列化。英特尔选择引入一个单独的指令,而不是改变RDTSC的行为,这表明我必须存在一些可能出现故障时序的情况。它是什么?

4 个答案:

答案 0 :(得分:12)

因为时间戳计数器是从内存引入奔腾的。

在Pentium Pro之前没有出现乱序执行,此时更改指令的内容为时已晚。

在您提供的文档中,实际上已经确认了这一点(以及关于Pentium和Pentium / MMX的以下评论)(4.2中略有释义):

  

4.1节(Pentium Pro和Pentium II)中描述的所有规则和代码示例也适用于Pentium和Pentium / MMX。唯一的区别是,序列化不需要CPUID指令。

而且,来自Wikipedia

  

自Pentium以来,时间戳计数器是所有x86处理器上的64位寄存器。

     

:::

     

从Pentium Pro开始,英特尔处理器支持无序执行,其中指令不一定按照它们在可执行文件中出现的顺序执行。这可能导致RDTSC的执行时间晚于预期,从而产生误导性的循环计数。


而且,根据我的理解,RDTSCP的主要使用(从i7开始)也是为了给你处理器ID,因为每个处理器都维护着一个独立的TSC。它可能是序列化的,但我发现更多的是一个简单的“bug修复”而不是旧的指令。

答案 1 :(得分:11)

如果您尝试使用rdtsc来查看分支是否错误预测,那么非序列化版本就是您想要的。

//math here
rdtsc
branch if zero to done
//do some work that always takes 1 cycle
done: rdtsc

如果正确预测分支,则delta会很小(甚至可能是负数?)。如果分支被错误预测,则增量将很大。

使用序列化版本,分支条件将被解决,因为第一个rdtsc等待数学完成。

答案 2 :(得分:7)

  

为什么他们不进行RDTSC序列化?它的全部要点似乎是获得周期准确的时间

好吧,大部分时间都是为了获得高分辨率的时间戳。至少在某些时候,这些时间戳用于性能指标。进行指令序列化可能需要管道刷新,这对于CPU绑定的应用程序来说可能非常昂贵。

  

英特尔选择引入一个单独的指令,而不是改变RDTSC的行为,这表明我必须存在一些可能出现故障时序的情况。

改变行为几乎总是不受欢迎的。英特尔的客户会发现RDTSC在新部件上做了不同的事情会感到失望。

答案 3 :(得分:3)

正如可以解释的那样,RDTSC早于“序列化”指令的概念,因为它是在有序CPU上实现的。稍后添加该行为将改变使用它的代码的内存访问行为,因此出于某些目的而不兼容。

相反,更新的CPU有一条相关的RDTSCP指令, 定义为序列化(实际上更强:它承诺等到所有指令发布在它之前已完成,不仅仅是已经完成了内存访问),正是出于这个原因。如果您在现代CPU上运行,请使用它。