多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间
多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间
陈硕
Blog.csdn.net/Solstice
自从 Intel Pentium 加入 RDTSC 指令以来,这条指令是 micro-benchmarking 的利器,可以以极小的代价获得高精度的 CPU 时钟周期数(Time Stamp Counter),不少介绍优化的文章[1]和书籍用它来比较两段代码的快慢。甚至有的代码用 RDTSC 指令来计时,以替换 gettimeofday() 之类的系统调用。在多核时代,RDTSC 指令的准确度大大削弱了,原因有三:
- 不能保证同一块主板上每个核的 TSC 是同步的;
- CPU 的时钟频率可能变化,例如笔记本电脑的节能功能;
- 乱序执行导致 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 指令测试指令周期和时间相关推荐
- X86中的RDTSC指令
Intel的X86中的RDTSC即Read Time Stamp Counter 读取时间计数器的指令.这个指令读取CPU时间计数器,返回一个无符号的64位整数.它通过EDX EAX寄存器返回CPU被 ...
- 多核时代,并行编程为何“臭名昭著”?
作者 | Yan Gu 来源 | 转载自知乎用户Yan Gu [导读]随着计算机技术的发展,毫无疑问现代计算机的处理速度和计算能力也越来越强.然而细心的同学们可能早已注意到,从2005年起,单核的 C ...
- java多核的利用率_java利用FutureTask、ExecutorService 在多核时代充分利用CPU运算
java利用FutureTask.ExecutorService 在多核时代充分利用CPU运算 FutureTask.ExecutorService 相关知识,请看java,API 一个使用Futur ...
- Amdahl定律以及该定律在多核时代的影响
Amdahl定律 不可并行计算的存在是很重要的,因为它将限制并行化的潜在好处.阿姆达尔定律指明如果一个计算的1/S本质上是顺序的,那么最大的性能改进将受限于因数S.其论证如下,一个并行计算的执行时间T ...
- 这个时代“寒门再难出贵子” (转帖)
这个时代"寒门再难出贵子" (转帖) 现在越来越看清楚"性格决定命运",性格这东西是熔透与骨髓的,性格的养成和学校教育没有多大关系,大多 ...
- 这个时代“寒门再难出贵子”
这个时代"寒门再难出贵子" 转载自: http://wenku.baidu.com/link?url=oZAEMECVBUtvfgsH5M8HR_rR_-nbIsYNRsSvvzj ...
- 这个时代——“寒门再难出贵子”,也许不服,不干,但想改变好比石头砸天(转自天涯)...
这个时代--"寒门再难出贵子", 也许不服,不干,但想改变好比石头砸天 现在越来越看清楚"性格决定命运",性格这东西是熔透于骨髓的,性格的养成和学校教育没有多大 ...
- Linux上采用rdtsc指令对C/C++程序进行性能测试
RDTSC是什么 RDTSC是 "Read Time Stamp Counter"的缩写,它是目前Intel和AMD的CPU都普遍支持的一条CPU指令,该指令可以把当前处理器的时间 ...
- 通过 RDTSC 指令从 CPU 寄存器中直接获取系统时钟
很多时候我们使用函数 gettimeofday 以及 clock_gettime 作为我们获取 wall lock的时钟函数. 因为这两种函数是 glibc 提供的用户封装,简单易用,而且能够精确到 ...
- MQTT再学习 -- 安装MQTT客户端及测试
上一篇文章我们已经讲了 MQTT 服务器的搭建,参看:MQTT再学习 -- 搭建MQTT服务器及测试 接下来我们看一下 MQTT 客户端. 一.客户端下载 首先,客户端也有多种,我们需要面临选择了. ...
最新文章
- 再见,Navicat!同事安利的这个IDEA的兄弟,真香!
- mongoose常用方法(查询篇)
- java实现留言版并回复_Java-留言板-回复页面(JSP)
- Android Binder总结
- 经典C语言程序100例之七一
- 【原创】Quartz代码详解
- php io流 读取wav,记php中的io流---帮助理解
- python应声虫代码_前端大牛们都学过哪些东西?
- python怎么弄成黑色背景图片_怎么能把图片的黑色背景改成透明背景
- ai老师人工智能培训老师计算机视觉老师叶梓:计算机视觉领域的自监督学习模型——MAE-12
- 我理解的二极管工作原理
- IDE工具、文本编辑器的列块编辑模式
- 机器学习(9)--决策树和随机森林
- word文件太大怎么压缩到最小-word压缩教程
- 自写密码字典-解口令具体过程(海德拉)
- 电脑显示不了WiFi的解决方法
- 基于opencv的人脸检测
- 正则表达式 (js)
- github汉化注意事项(Chrome)
- 自投递简历以来的第一次面试