多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间

原创 2010年01月16日 00:24:00

多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间

 

陈硕
Blog.csdn.net/Solstice

 

自从 Intel Pentium 加入 RDTSC 指令以来,这条指令是 micro-benchmarking 的利器,可以以极小的代价获得高精度的 CPU 时钟周期数(Time Stamp Counter),不少介绍优化的文章[1]和书籍用它来比较两段代码的快慢。甚至有的代码用 RDTSC 指令来计时,以替换 gettimeofday() 之类的系统调用。在多核时代,RDTSC 指令的准确度大大削弱了,原因有三:

 

  1. 不能保证同一块主板上每个核的 TSC 是同步的;
  2. CPU 的时钟频率可能变化,例如笔记本电脑的节能功能;
  3. 乱序执行导致 RDTSC 测得的周期数不准,这个问题从 Pentium Pro 时代就存在。

 

这些都影响了 RDTSC 的两大用途,micro-benchmarking 和计时。

 

RDTSC 一般的用法是,先后执行两次,记下两个 64-bit 整数 start 和 end,那么 end-start 代表了这期间 CPU 的时钟周期数。

 

在多核下,这两次执行可能会在两个 CPU 上发生,而这两个 CPU 的计数器的初值不一定相同(由于完成上电复位的准确时机不同),(有办法同步,见[3]),那么就导致 micro-benchmarking 的结果包含了这个误差,这个误差可正可负,取决于先执行的那块 CPU 的时钟计数器是超前还是落后。

 

另外,对于计时这个用途,时间 = 周期数 / 频率,由于频率可能会变(比如我的笔记本的 CPU 通常半速运行在 800MHz,繁忙的时候全速运行在 1.6GHz),那么测得的时间也就不准确了。有的新 CPU 的 RDTSC 计数频率是恒定的,那么时钟是准了,那又会导致 micro-benchmarking 的结果不准,见 [2]。还有一个可能是掉电之后恢复(比如休眠),那么 TSC 会清零。 总之,用 RDTSC 来计时是不灵的。

 

乱序执行这个问题比较简单 [1],但意义深远:在现代 CPU 的复杂架构下,测量几条或几十条指令的耗时是无意义的,因为观测本身会干扰 CPU 的执行(cache, 流水线, 多发射,乱序, 猜测),这听上去有点像量子力学系统了。要么我们以更宏观的指标来标示性能,把"花 xxx 个时钟周期"替换"每秒处理 yyy 条消息"或"消息处理的延时为 zzz 毫秒";要么用专门的 profiler 来减小对观测结果的影响(无论是 callgrind 这种虚拟 CPU,还是 OProfile 这种采样器)。

 

虽然 RDTSC 废掉了,性能测试用的高精度计时还是有办法的 [2],在 Windows 用 QueryPerformanceCounter 和 QueryPerformanceFrequency,Linux 下用 POSIX 的 clock_gettime 函数,以 CLOCK_MONOTONIC 参数调用。或者按文献 [3] 的办法,先同步 TSC, 再使用它。(我不知道现在最新的 Linux 官方内核是不是内置了这个同步算法。也不清楚校准后的两个 CPU 的“钟”会不会再次失步。)

 

[1] http://www.ccsl.carleton.ca/~jamuir/rdtscpm1.pdf
[2] http://en.wikipedia.org/wiki/Time_Stamp_Counter

[3] x86: unify/rewrite SMP TSC sync code http://lwn.net/Articles/211051/

相关文章推荐

RDTSC命令详解

RDTSC - 读取时间标签计数器操作码指令说明0F 31RDTSC将时间标签计数器读入 EDX:EAX说明将处理器的时间标签计数器的当前值加载到 EDX:EAX 寄存器。时间标签计数器包含在 64 ...
  • TBWood
  • TBWood
  • 2010年04月27日 21:55
  • 21608

RDTSC指令实现纳秒级计时器

   X86 platform    从pentium开始,很多80x86微处理器都引入TSC,一个用于时间戳计数器的64位的寄存器,它在每个时钟信号(CLK, CLK是微处理器中一条用于接收外部振荡...
  • gonxi
  • gonxi
  • 2010年12月29日 13:43
  • 6887

如何利用rdtsc计算纳秒级的时间

从奔腾系列开始,Intel X86 处理器中增加了一个64位的时间戳寄存器(TSC),每个经过一个时钟周期,该寄存器加1;机器重启时,该寄存器将清空。     现在的处理器其主频都在1G以上,也就是说...

linux编程的108种奇淫巧计-2(RDTSC)

通常我们需要对程序运行的准确时间进行测量,但多线程,多核环境下,这变得很困难,我们有没有一种比较通用简单的方法来做到这一点呢?这些方法都存在哪些问题,如何改进可以抵消这些误差呢? ...

用rdtsc实现linux下的精确计时

转自:http://blog.csdn.net/x86/article/details/2235267 在linux开发版最长问到的问题之一就是在linux下如何得到更精确的计时。其实有很多办法,比...

再论 Time stamp counter

http://www.cnblogs.com/ralphjzhang/archive/2012/01/09/2317463.html 在很多年以前,rdtsc 指令是在 x86 平台作 mi...

关于RDTSC和CPU调频

 RDTSC不过是个特定CPU支持的指令,这个指令将计算机启动以来的CPU运行周期数放到EDX:EAX寄存器中,EDX是高位,EAX是低位。如下//CPU时间戳,用来获取机器周期数。unsigned ...

多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间

多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间   陈硕 Blog.csdn.net/Solstice   自从 Intel Pentium 加入 RDTS...

用rdrtc实现linux下的精确计时

在linux开发版最长问到的问题之一就是在linux下如何得到更精确的计时。其实有很多办法,比如以前就有人用select。不过现在有更精确的实时时钟可以用,这就是用CLOCK_PROCESS_CPUT...
  • x86
  • x86
  • 2008年04月01日 11:23
  • 3014

linux时钟处理机制(一)

计算机系统中的计时器 在计算机系统中存在着许多硬件计时器,例如 Real Timer Clock ( RTC )、Time Stamp Counter ( TSC ) 和 Programmable ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间
举报原因:
原因补充:

(最多只允许输入30个字)