會用到以下的方法:
-C++中用Assembler語法(RDTSC)
-QueryPerformanceCounter
-timeGetTime
-GetTickCount
-clock
說明:
-C++中用Assembler語法
用的方法就是所謂的RDTSC(Read Time Stamp Counter),他是Intel CPU從Pentium以上就提供的timestamp值,單位是64位元的微秒(us)值。有一說C++ compiler不認得RDTSC,所以透過直接控制機碼(0x0F, 0x31)的方式可以達到。既然是CPU timestamp,理論上可以達到奈秒(ns)等級,不過實際上很多討論是說省電機制,新製程或是雙核以上CPU,這些都會造成CPU頻率漂移,因此得到的這個值就大大不準了,要是一個長時間等待的計算,中間頻率一變動,換算下來都是錯的。
inline unsigned __int64 GetCycleCount() { __asm _emit 0x0F __asm _emit 0x31 }
-QueryPerformanceCounter
Windows的高精度Timer,單位是64位元的微秒(us)值,搭配QueryPerformanceFrequency返回的硬體計數器的頻率(一般是CPU頻率)來看,運用2次的QueryPerformanceCounter取得的值,再去除以頻率,就可以得到時間。由於這個是Windows API的最精確Timer,所以我用這個函式來當作頭尾的時間抓取,中間再去擺放不同方式做的等待時間,最後差值來看比較結果。
QueryPerformanceFrequency((LARGE_INTEGER *)&frequency) QueryPerformanceCounter((LARGE_INTEGER *)&counter)
- timeGetTime
這個是從系統啟動到被調用這個函式的時間,單位是一個32位元的毫秒(ms)值
#include <mmsystem.h> #pragma comment(lib, "winmm.lib") DWORD timeGetTime(void)
- GetTickCount
和上頭一樣是返回系統時間,單位是一個32位元的毫秒(ms)值
#include <windows.h> DWORD GetTickCount(void)
- clock
和上頭一樣,但返回的是CPU的clock tick數,單位是一個long的值
clock_t clock(void)
然後以上具備之後,對每一種方法實做一個while loop等待,用的方式是等待同時也可以讓message收送,才不會都被這個while迴圈堵住:
now=end=0; end = GetTime(); while(now<end+WaitTime){ if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE)){ if(msg.message==WM_QUIT){ ::PostQuitMessage(0); } else{ ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } now = GetTime(); }
--程式執行圖--
最後我還是有加上Sleep的等待來比較一下,顯示單位是毫秒(ms)。可以看出,在我電腦RDTSC和QueryPerformanceCounter的效果最好,誤差在微秒(us)等級,最準。而clock的方法就比較差。因此之後需要做一個等待時間的函數,應該選擇的就是QueryPerformanceCounter。
--完整Source Code(VC++ 2008 vaildated)
0 意見:
張貼留言