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

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

  1. X86中的RDTSC指令

    Intel的X86中的RDTSC即Read Time Stamp Counter 读取时间计数器的指令.这个指令读取CPU时间计数器,返回一个无符号的64位整数.它通过EDX EAX寄存器返回CPU被 ...

  2. 多核时代,并行编程为何“臭名昭著”?

    作者 | Yan Gu 来源 | 转载自知乎用户Yan Gu [导读]随着计算机技术的发展,毫无疑问现代计算机的处理速度和计算能力也越来越强.然而细心的同学们可能早已注意到,从2005年起,单核的 C ...

  3. java多核的利用率_java利用FutureTask、ExecutorService 在多核时代充分利用CPU运算

    java利用FutureTask.ExecutorService 在多核时代充分利用CPU运算 FutureTask.ExecutorService 相关知识,请看java,API 一个使用Futur ...

  4. Amdahl定律以及该定律在多核时代的影响

    Amdahl定律 不可并行计算的存在是很重要的,因为它将限制并行化的潜在好处.阿姆达尔定律指明如果一个计算的1/S本质上是顺序的,那么最大的性能改进将受限于因数S.其论证如下,一个并行计算的执行时间T ...

  5. 这个时代“寒门再难出贵子” (转帖)

    这个时代"寒门再难出贵子" (转帖)             现在越来越看清楚"性格决定命运",性格这东西是熔透与骨髓的,性格的养成和学校教育没有多大关系,大多 ...

  6. 这个时代“寒门再难出贵子”

    这个时代"寒门再难出贵子" 转载自: http://wenku.baidu.com/link?url=oZAEMECVBUtvfgsH5M8HR_rR_-nbIsYNRsSvvzj ...

  7. 这个时代——“寒门再难出贵子”,也许不服,不干,但想改变好比石头砸天(转自天涯)...

    这个时代--"寒门再难出贵子", 也许不服,不干,但想改变好比石头砸天 现在越来越看清楚"性格决定命运",性格这东西是熔透于骨髓的,性格的养成和学校教育没有多大 ...

  8. Linux上采用rdtsc指令对C/C++程序进行性能测试

    RDTSC是什么 RDTSC是 "Read Time Stamp Counter"的缩写,它是目前Intel和AMD的CPU都普遍支持的一条CPU指令,该指令可以把当前处理器的时间 ...

  9. 通过 RDTSC 指令从 CPU 寄存器中直接获取系统时钟

    很多时候我们使用函数 gettimeofday 以及 clock_gettime 作为我们获取 wall lock的时钟函数. 因为这两种函数是 glibc 提供的用户封装,简单易用,而且能够精确到 ...

  10. MQTT再学习 -- 安装MQTT客户端及测试

    上一篇文章我们已经讲了 MQTT 服务器的搭建,参看:MQTT再学习 -- 搭建MQTT服务器及测试 接下来我们看一下 MQTT 客户端. 一.客户端下载 首先,客户端也有多种,我们需要面临选择了. ...

最新文章

  1. 再见,Navicat!同事安利的这个IDEA的兄弟,真香!
  2. mongoose常用方法(查询篇)
  3. java实现留言版并回复_Java-留言板-回复页面(JSP)
  4. Android Binder总结
  5. 经典C语言程序100例之七一
  6. 【原创】Quartz代码详解
  7. php io流 读取wav,记php中的io流---帮助理解
  8. python应声虫代码_前端大牛们都学过哪些东西?
  9. python怎么弄成黑色背景图片_怎么能把图片的黑色背景改成透明背景
  10. ai老师人工智能培训老师计算机视觉老师叶梓:计算机视觉领域的自监督学习模型——MAE-12
  11. 我理解的二极管工作原理
  12. IDE工具、文本编辑器的列块编辑模式
  13. 机器学习(9)--决策树和随机森林
  14. word文件太大怎么压缩到最小-word压缩教程
  15. 自写密码字典-解口令具体过程(海德拉)
  16. 电脑显示不了WiFi的解决方法
  17. 基于opencv的人脸检测
  18. 正则表达式 (js)
  19. github汉化注意事项(Chrome)
  20. 自投递简历以来的第一次面试

热门文章

  1. 不使用随机数的洗牌算法
  2. HDU2602Bone Collector(DP,0/1背包)
  3. 读懂hadoop、hbase、hive、spark分布式系统架构
  4. DHCP中继数据包互联网周游记
  5. 删除密码设置对象(PSO)
  6. Oracle如何一次插入多条数据
  7. OC对象之旅 weak弱引用实现分析
  8. 统一Retrofit失败的处理情况
  9. JMeter入门合集
  10. 关于弱电工程图纸的几个常见问题