有时,我会遇到用rdtsc指令读取TSC的代码,但就在前面调用cpuid。
为什么调用cpuid是必要的?我意识到这可能与具有TSC值的不同内核有关,但是当您按顺序调用这两个指令时会发生什么呢?
发布于 2010-05-27 02:32:39
这是为了防止无序处决。从现在已从网络上消失的链接(但在它消失之前碰巧被复制到这里),本文摘自John Eckerdal的一篇题为“性能监控”的文章:
,奔腾Pro和奔腾II处理器,支持无序的执行指令,可以在您编程时以另一个顺序执行。如果不加以处理,这可能是错误的来源。
为了防止这种情况,程序员必须序列化指令队列。这可以通过在RDTSC指令之前插入一个类似CPUID的序列化指令来完成。。
发布于 2012-06-08 06:53:33
原因有二:
发布于 2019-01-16 09:49:48
CPUID正在序列化,防止RDTSC的无序执行.
现在,您可以安全地使用LFENCE。它被记录为在Intel CPU上的指令流(但不是存储到内存中)上序列化,现在也在AMD上,在它们的谱微代码更新之后。
https://hadibrais.wordpress.com/2018/05/14/the-significance-of-the-x86-lfence-instruction/解释了更多关于LFENCE的内容。
还请参阅https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf以获得一种使用RDTSC(或LFENCE)远离定时区域的https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdfP的方法:
LFENCE ; (or CPUID) Don't start the timed region until everything above has executed
RDTSC ; EDX:EAX = timestamp
mov ebx, eax ; low 32 bits of start time
code under test
RDTSCP ; built-in one way barrier stops it from running early
LFENCE ; (or CPUID) still use a barrier after to prevent anything weird
sub eax, ebx ; low 32 bits of end-start有关RDTSC的更多信息,请参见Get CPU cycle count?,如constant_tsc和nonstop_tsc。
作为奖励,RDTSCP为您提供了一个核心ID。如果您想检查核心迁移,也可以使用RDTSCP作为启动时间。但是,如果您的CPU具有constant_tsc功能,则包中的所有核心都应该同步它们的TSC,因此在现代x86上通常不需要这样做。
您可以从CPUID获得核心ID,正如@Tony的回答所指出的那样。
https://stackoverflow.com/questions/2918113
复制相似问题