花了很长时间才获得的经验,与你们分享。
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)
----------------------------------------------ios