获取高精度时间注意事项 (QueryPerformanceCounter , QueryPerformanceFrequency)
花了很长时间才得到的经验,与大家分享。
1. RDTSC - 粒度: 纳秒级 不推荐
优势: 几乎是能够获得最细粒度的计数器
抛弃理由:
A) 定义模糊
- 曾经据说是处理器的cycle counter,但是后来似乎又不是了。
有的机器上每秒的TSC增长值等于CPU频率,有的却是一个不对应任何配置的数。到底是什么,Intel也没解释清楚。
B) 不准确
- 这是最重大的缺陷。再细的粒度,不准的话也没用,至少不能当时间用。
在有的CPU上,特别是支持变频技术的笔记本CPU上,TSC增长值会随着CPU的频率改变。忙的时候跑得快,闲得时候跑得慢。
2. QueryPerformanceCounter - 粒度: 1~100微秒级 不推荐
优势: 尽管比RDTSC粒度稍低,但是不存在RDTSC在变频CPU上的问题。
知道这个API的人估计都倾向于用这个,因为M$对这个API给出了比较明确的定义,就是每秒钟某个计数器增长的数值。
抛弃理由: 还是不准确
尽管没有源代码,但是从M$的帮助文档和知识库可以了解到,PerformanceCounter是依赖于主板上与PCI设备有关联的硬件。这就意味着,PerformanceCounter的结果还是会受到硬件频率,特别是总线频率的影响。
事实上,我在EeePC上测试的时候就发现,系统采用节能模式的时候PerformanceCounter出来的结果老是偏慢很多,超频模式的时候又偏快,而且用电池和接电源的时候效果还不一样!
3. timeGetTime - 粒度: 毫秒级 推荐
尽管粒度进一步降低,但是其无与伦比的优势就是,准确。
在任何机器上返回的都是当前系统的启动时间,精确到1毫秒。
使用注意事项:
A) 在NT系统上(据说)默认精度为10ms,但是可以用timeBeginPeriod来降低到1ms
B) 返回的是一个32位整数,所以要注意大约每49.71天会出现归零(不像前两个是64位数,要几百年才会归零)。
----------------------------------------------
-
实际上timeGetTime以及GetTickCount也是由QueryPerformanceCounter/QueryPerformanceFrequency得到的,因为做了除以频率的操作,所以得到的数值比较客观,准确
明显不是的。
我的代码就是用QueryPerformanceCounter / QueryPerformanceFrequency得到实际经过的时间。
测试方法为: 调用时间API, Sleep 500ms, 再调用时间API, 不停的循环。
用 两次timeGetTime的差值得到经过的毫秒数 (简称 Tick)
与 两次QueryPerformanceCounter的差值/QueryPerformanceFrequency得到经过的毫秒数 (简称 Counter)
比较发现:
在EeePC 正常模式下: Tick: 500ms, Counter: 500ms
在超频模式下: Tick: 500ms, Counter: 535ms
在节能模式下: Tick: 500ms, Counter: 260ms
可见用多媒体时钟timeGetTime始终是稳定的,但是PerformanceCounter就不行了。
----------------------------------------------
-
M$的有一个KB上提到芯片组Bug导致QueryPerformanceCounter有时候会往前跳几秒。描述原因的时候说是因为芯片组在PCI Bus上的Bug导致系统接受到奇怪的消息,系统为了保证稳定就会往PerformanceCounter上加几秒钟。从这个描述上就可以看出,PerformanceCounter是以PCI Bus的某个硬件作为基础的。
事实上,有的人说PerformanceCounter是系统接受的IRQ#0的计数器,但是还有一种说法是,在有的系统上PerformanceCounter会使用CPU的TSC...
总之,Performance Counter也不是一个可以100%靠得住的时间源。
要想你的代码在大量配置不同的机器上不出问题,目前只有依赖timerGetTime这个多媒体时钟。
----------------------------------------------
-
大概瞅了一下intel manual,vol3b (system programming guide B)里ch18第11和20节讲的是关于计时的
手册2b里RDTSC中除了说3b的18章外,还提到了3b的21章,这些你都仔细读过了之后得到上述关于RDTSC的结论的么?
er... 我的是经验,不是结论。靠读manual是不可能得到的,是我花了很长时间在很多机器上试验得到的结果。
有的机器上RDTSC的增幅是和频率一致的,但是多数是台式机,而且是老型号。
新的台式机和笔记本CPU的RDTSC的增幅明显不是频率,有说法是总线的主频。
Pentium M的TSC会随着speedstep变化;服务器的好像还挺稳定,但是我没有打开Linux内核的CPU Frequency Scaling,说不定打开了以后也会出现这个现象。
在多CPU下,每一个CPU的RDTSC是独立的;SMP下运行的线程可能会被放到不同的CPU下运行,这意味着两次读TSC可能会出现后面比前面小的情况,所以最好还要SetThreadAffinity,绑定在一块CPU上。
总之TSC用起来也很麻烦,而且太底层,很难在不同的配置下兼容。这个东西用来做单个机器的Profiling不错(本来就是为了这个目的),但是如果当成时间源的话就差了。
----------------------------------------------
-
我建议吧,和硬件有关的东西还是直接看官方的manual,贷是人家设计的,手册不可能还没你的经验靠谱
下面这段是vol 3b ch18.20中最开头的部分,建议你在自己已经做过之前,不要轻易下“靠读manual是不可能得到的”这种结论
The count of cycles, also known as clockticks, forms a the basis for measuring how
long a program takes to execute. Clockticks are also used as part of efficiency ratios
like cycles per instruction (CPI). Processor clocks may stop ticking under circum-
stances like the following:
? The processor is halted when there is nothing for the CPU to do. For example, the
processor may halt to save power while the computer is servicing an I/O request.
When Intel Hyper-Threading Technology is enabled, both logical processors must
be halted for performance-monitoring counters to be powered down.
? The processor is asleep as a result of being halted or because of a power-
management scheme. There are different levels of sleep. In the some deep sleep
levels, the time-stamp counter stops counting.
In addition, processor core clocks may undergo transitions at different ratios relative
to the processor’s bus clock frequency. Some of the situations that can cause
processor core clock to undergo frequency transitions include:
? TM2 transitions
? Enhanced Intel SpeedStep Technology transitions (P-state transitions)
----------------------------------------------
获取高精度时间注意事项 (QueryPerformanceCounter , QueryPerformanceFrequency)的更多相关文章
- Windows下获取高精度时间注意事项
Windows下获取高精度时间注意事项 [转贴 AdamWu] 花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: ...
- Windows下获取高精度时间注意事项 [转贴 AdamWu]
花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: A) 定义模糊 - 曾经据说是处理器的cycle counter, ...
- 一个 C# 获取高精度时间类(调用API QueryP*)
如果你觉得用 DotNet 自带的 DateTime 获取的时间精度不够,解决的方法是通过调用 QueryPerformanceFrequency 和 QueryPerformanceCounter这 ...
- .net平台下获取高精度时间类
原文:http://www.it118.org/specials/321869dd-98cb-431b-b6d2-82d973cd739d/d940a15c-0d36-4369-8de0-b07cf3 ...
- VC中如何获取当前时间(精度达到毫秒级)
标 题: VC中如何获取当前时间(精度达到毫秒级)作 者: 0xFFFFCCCC时 间: 2013-06-24链 接: http://www.cnblogs.com/Y4ng/p/Millisecon ...
- 【vc】高精度时间函数的使用
方法一: 函数定义如下: int UsSleep(int us);//返回实际的微秒延时时间 代码实现如下: //参数一表示 需要等待的时间 微秒为单位 int UsSleep(int us) { / ...
- 【转】cocos2d-x获取系统时间——2013-08-25 10
欢迎转载,本帖地址:http://blog.csdn.net/jinjian2009/article/details/9449585 之前使用过cocos2d-x获取系统时间,毫秒级的 long ge ...
- cocos2d-x获取系统时间
欢迎转载,本帖地址:http://blog.csdn.net/jinjian2009/article/details/9449585 之前使用过cocos2d-x获取系统时间,毫秒级的 long ge ...
- 浅析libuv源码-获取精确时间
在Timer模块中有提到,libuv控制着延迟事件的触发,那么必须想办法精确控制时间. 如果是JS,获取当前时间可以直接通过Date.now()得到一个时间戳,然后将两段时间戳相减得到时间差.一般情况 ...
随机推荐
- MT2017笔试题
一.大富翁游戏 1.题目 大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步.求玩家走到第n步(n<=骰子最大点数且是方法的唯一入 ...
- ios 自动化构建 code-select: error: tool 'xcodebuild' requires Xcode, but active developer directory.....
问题描述: Pod installation complete! There are 2 dependencies from the Podfile and 3 total pods installe ...
- Python爬虫入门教程 26-100 知乎文章图片爬取器之二
1. 知乎文章图片爬取器之二博客背景 昨天写了知乎文章图片爬取器的一部分代码,针对知乎问题的答案json进行了数据抓取,博客中出现了部分写死的内容,今天把那部分信息调整完毕,并且将图片下载完善到代码中 ...
- C++中 引用&与取地址&的区别
微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...
- Chapter 5 Blood Type——26
"I saw his face — I could tell." “我看到他的脸了 —— 我知道.” "How did you see me? I thought you ...
- 补习系列(2)-springboot mime类型处理
目标 了解http常见的mime类型定义: 如何使用springboot 处理json请求及响应: 如何使用springboot 处理 xml请求及响应: http参数的获取及文件上传下载: 如何获得 ...
- 磊哥评测之数据库:腾讯云MongoDB vs自建
本文由云+社区发表 作者:磊哥 上期文章我们聊到了redis.这期我们来说说另一个网红nosql数据库:MongoDB.有这么一个介绍MongoDB的说法是:MongoDB是非关系数据库当中功能最丰富 ...
- 关于 vue 不能 watch 数组变化 和 对象变化的解决方案
原文地址:关于 vue 不能 watch 数组变化 和 对象变化的解决方案 vue 监听数组和对象的变化 vue 监听数组 vue 实际上可以监听数组变化,比如: data () { return { ...
- DSAPI HTTP监听服务端与客户端
本文中,演示了使用DSAPI.网络相关.HTTP监听,快速建立服务端和客户端. HTTP监听服务端的作用,是监听指定计算机端口,以实现与IIS相同的解析服务,提供客户端的网页请求,当然,这不仅仅是应用 ...
- DSAPI多功能组件编程应用-网络相关(下)
[DSAPI.DLL下载地址] 在本篇,我将重点介绍DSAPI.DLL中Socket编程的使用.众所周知,Socket用起来不难,但是写起来麻烦.我对Socket进行了封装,进行了高度简化.下面我将通 ...