花了很长时间才得到的经验,与大家分享。

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)的更多相关文章

  1. Windows下获取高精度时间注意事项

    Windows下获取高精度时间注意事项 [转贴 AdamWu]   花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: ...

  2. Windows下获取高精度时间注意事项 [转贴 AdamWu]

    花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: A) 定义模糊 - 曾经据说是处理器的cycle counter, ...

  3. 一个 C# 获取高精度时间类(调用API QueryP*)

    如果你觉得用 DotNet 自带的 DateTime 获取的时间精度不够,解决的方法是通过调用 QueryPerformanceFrequency 和 QueryPerformanceCounter这 ...

  4. .net平台下获取高精度时间类

    原文:http://www.it118.org/specials/321869dd-98cb-431b-b6d2-82d973cd739d/d940a15c-0d36-4369-8de0-b07cf3 ...

  5. VC中如何获取当前时间(精度达到毫秒级)

    标 题: VC中如何获取当前时间(精度达到毫秒级)作 者: 0xFFFFCCCC时 间: 2013-06-24链 接: http://www.cnblogs.com/Y4ng/p/Millisecon ...

  6. 【vc】高精度时间函数的使用

    方法一: 函数定义如下: int UsSleep(int us);//返回实际的微秒延时时间 代码实现如下: //参数一表示 需要等待的时间 微秒为单位 int UsSleep(int us) { / ...

  7. 【转】cocos2d-x获取系统时间——2013-08-25 10

    欢迎转载,本帖地址:http://blog.csdn.net/jinjian2009/article/details/9449585 之前使用过cocos2d-x获取系统时间,毫秒级的 long ge ...

  8. cocos2d-x获取系统时间

    欢迎转载,本帖地址:http://blog.csdn.net/jinjian2009/article/details/9449585 之前使用过cocos2d-x获取系统时间,毫秒级的 long ge ...

  9. 浅析libuv源码-获取精确时间

    在Timer模块中有提到,libuv控制着延迟事件的触发,那么必须想办法精确控制时间. 如果是JS,获取当前时间可以直接通过Date.now()得到一个时间戳,然后将两段时间戳相减得到时间差.一般情况 ...

随机推荐

  1. asp.net mvc简单实现基于Razor的分页控件

    最近在写一些web应用了解了一下asp.net mvc发现的确好用,所以直接就干上了.不过在使用asp.net mvc的Razor模板的情况并不向传统webform那样可以使用控件.但从Razor的功 ...

  2. 初学Java Web(5)——cookie-session学习

    HTTP 协议 Web 浏览器与 Web 服务器之间的一问一答的交互过程必须遵守一定的规则,这样的规则就是 HTTP 协议. HTTP 是 hypertext transfer protocol(超文 ...

  3. Linux基础知识第九讲,linux中的解压缩,以及软件安装命令

    目录 Linux基础知识第九讲,linux中的解压缩,以及软件安装命令 一丶Linux Mac Windows下的压缩格式简介 2.压缩以及解压缩 3.linux中的软件安装以及卸载 1.apt进行安 ...

  4. 想晋级高级工程师只知道表面是不够的!Git内部原理介绍

    本文由云+社区发表 作者:腾讯工蜂用户:王二卫 从不一样的视角了解git,以便更好的使用git 一.git & git 版本库认识 git 是一个内容寻址的文件系统,其核心部分是一个简单的键值 ...

  5. 【Node.js】二、基于Express框架 + 连接MongoDB + 写后端接口

    在上节,我们讲了如何搭建express环境,现在我们说说如何通过node.js写服务接口给前端调用 1. 首先通过MongoDB建好数据库与表格 例如,我的数据库名字为db_demo,数据库表格为go ...

  6. 【原创】PicUploader: 一个还不错的图床工具

    PicUploader PicUploader 是一个用php编写的图床工具,它能帮助你快速上传你的图片到云图床,并自动返回Markdown格式链接到剪贴板.配置完成后,要获取一个可用于markdow ...

  7. win10下rdlc报表在vs(visual studio)中中文显示小方块的批量处理解决方法

    在网上找vs中rdlc报表显示中文时显示小方块的解决方案,无外就是修改文本框的字体属性.但是对于维护已有的rdlc报表时,有中文的地方(此时都显示了小方块)会很多,再一个一个设置实在太麻烦.所以自己花 ...

  8. 程序员50题(JS版本)(二)

    程序6:用*号输出字母C的图案 console.log(' ****'); console.log(' ***'); console.log(' **'); console.log(' *'); co ...

  9. Sublime Text 快捷键列表

    Sublime Text 快捷键列表 快捷键按类型分列如下: 补充:1.快速的创建一个html页 :ctrl+n创建一个新的文件-->右下角选择文件类型-->输入英文"!&quo ...

  10. 【20190304】JavaScript-知识点总结:Set,异或

    ES6新特性:Set ES6提供了新的数据结构Set,Set对象不是数组, 可以用来保存对象或者基本类型, 所有保存的值都是唯一的, chrome浏览器>38和FF>13,以及nodeJS ...