多核时代不宜再用 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/

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

dpdk l2fwd 应用流程分析

int MAIN(int argc, char **argv) { struct lcore_queue_conf *qconf; struct rte_eth_dev_info de...

C语言中常用计时方法总结

C语言中常用计时方法总结 1. time() 头文件:time.h 函数原型:time_t time(time_t * timer) 功能:返回以格林尼治时间(GMT)为标准,从1970年...
  • fz_ywj
  • fz_ywj
  • 2012-10-25 09:46
  • 27978

Linux中的时钟与时间

日期:2010-02-04作者:Steven Yang邮箱:mqyoung@gmail.com注:转载请注明出处和作者并保持文档的完整 HZ内核通过定时器中断来跟踪时间流,时钟中断由系统定时硬件以周期...

RDTSC指令实现纳秒级计时器

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

RDTSC命令详解

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

用rdtsc实现linux下的精确计时

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

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

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

Win32控件使用——Edit控件

Drecik学习经验分享 转载请注明出处:http://blog.csdn.net/drecik__/article/details/8112844 Edit控件是一个很强大的输入控件,可...

win32 edit控件尾部追加内容

有时候我们可能想在win32程序上实时打印我们想要的一些信息,不是以覆盖的形式而是以追加的形式。     以前我常常采用比较笨的方式,首先调用GetDlgItemText获取原先字符串,保存在一个字符...

Win32——edit控件的简单使用

虽然标题是Win32 edit 控件的简单使用,不过最主要的还是记录第一次做操作系统实验中遇到的问题。由于是第一次做Win32 的编程,如果在解释上有错误,欢迎指正! 在创建一个Win32 应用工程...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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