[Intel manuals for the RDTSC instruction警告,当实际执行RDTSC时,乱序执行可能会改变,因此他们建议在其前面插入CPUID指令,因为CPUID会序列化指令流(永远不会乱序执行CPUID)。我的问题很简单:如果他们能够进行指令序列化,为什么不进行RDTSC序列化呢?它的全部目的似乎是要获得精确的周期计时。是否有一种情况,您会not想要在其前面加上序列化指令?
较新的Intel CPU具有单独的RDTSCP指令,该指令正在序列化。英特尔选择引入单独的指令,而不是改变RDTSC的行为,这向我暗示,在某些情况下,您想要的是潜在的乱序时间。这是什么?
如果您尝试使用rdtsc来查看分支是否预测错误,则需要非序列化版本。
//math here
rdtsc
branch if zero to done
//do some work that always takes 1 cycle
done: rdtsc
如果正确预测了分支,则增量将很小(甚至可能为负?)。如果分支预测错误,则增量将很大。
使用序列化版本,将解决分支条件,因为第一个rdtsc等待数学完成。
时间戳计数器是在奔腾微体系结构上引入的。直到奔腾Pro才出现乱序执行。英特尔本来可以(架构上或内部)进行rdtsc
序列化,但似乎他们决定使其保持非序列化,这对于通用时间测量是可以的,并留给程序员在必要时添加序列化指令。这有利于减少测量的开销。
您提供的文档中实际上已经确认,并带有以下有关Pentium和Pentium / MMX的注释(在4.2中,稍有措辞):
第4.1节(Pentium Pro和Pentium II)中描述的所有规则和代码示例也适用于Pentium和Pentium / MMX。唯一的区别是,串行化不需要CPUID指令。
并且,来自Wikipedia:
时间戳记计数器是奔腾以来所有x86处理器上都存在的64位寄存器。
:::
[从奔腾Pro开始,英特尔处理器支持乱序执行,其中指令不一定按照它们在可执行文件中出现的顺序执行。这可能导致RDTSC的执行时间比预期的晚,从而产生误导的周期计数。
RDTSCP的两种用途之一是为时间戳信息提供addition中的处理器ID(名称为Read Time-Stamp Counter *AND* Processor ID
),这在跨TSC不同步的系统上非常有用芯或插座(请参阅:How to get the CPU cycle count in x86_64 from C++?)。 rdtscp
的附加序列化属性使它在感兴趣区域的末端更加方便(请参阅:Is there any difference in between (rdtsc + lfence + rdtsc) and (rdtsc + rdtscp) in measuring execution time?)。
他们为什么不对RDTSC进行序列化?它的全部目的似乎是要获得精确的周期计时]
嗯,大多数时候都是要获得高分辨率的时间戳。这些时间戳至少在某些时候用于性能指标。进行指令序列化可能需要管道刷新,这对于绑定CPU的应用程序可能非常昂贵。
[Intel选择引入单独的指令,而不是改变RDTSC的行为,这向我表明,在某些情况下,您想要的是潜在的乱序时间。
更改行为几乎总是不希望的。英特尔的客户会失望地发现RDTSC
在较新的部件上有不同之处。
[如合理解释,RDTSC
早于“序列化”指令的概念,因为它是在有序CPU上实现的。稍后添加该行为将更改使用该行为的代码的内存访问行为,因此出于某些目的不兼容。
相反,较新的CPU具有相关的RDTSCP
指令,该指令[