QueryPerformanceFrequency用法--Windows高精度定時計數

在多核心或多處理器的計算機上,特別是在支持CPU頻率動態調整的計算機上,windows系統下的QueryPerformanceFrequency()獲取HPET(如果存在)的頻率,而QueryPerformanceCounter()獲取HPET(如果存在高精度事件定時器(High Precision Event Timer))自上電以來時鐘週期數,與CPU頻率無關。前一個函數不會因爲線程運行所在的CPU不同或CPU的頻率在不同時刻的差異而反饋不同的值,系統上電初始化以後便不會改變,後一個函數的源也是統一的。這樣便可以精確計算目標程序,特別是多線程程序的性能。

如果想獲得CPU的默認信息,包括製造商,版本號,默認頻率等等,請使用:__cpuid()。如果想獲得當前CPU的實際頻率,請獲取系統當前基頻和倍頻然後計算得到。

           注:但是這和程序具體的運行環境有關,程序運行的流暢順利就所用的時間就短,程序運行的環境不好,持續時間久很長。

           故雖然可以實現高精度定時計數,但是程序的執行時間還是和運行環境有關,無法做到精確測量。

精確獲取時間:

QueryPerformanceFrequency() - 基本介紹

類型:Win32API

原型:BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

作用:返回硬件支持的高精度計數器的頻率。

返回值:非零,硬件支持高精度計數器;零,硬件不支持,讀取失敗。

QueryPerformanceFrequency() - 技術特點

供WIN9X使用的高精度定時器:QueryPerformanceFrequency()和QueryPerformanceCounter(),要求計算機從硬件上支持高精度定時器。需包含windows.h頭文件。

函數的原形是:

BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount);

數據類型LARGEINTEGER既可以是一個作爲8字節長的整數,也可以是作爲兩個4字節長的整數的聯合結構,其具體用法根據編譯器是否支持64位而定。該類型的定義如下:

typeef union _ LARGE_INTEGER

{

struct

{

DWORD LowPart;

LONG HighPart;

};

LONGLONG QuadPart;

} LARGE_INTEGER;


在定時前應該先調用QueryPerformanceFrequency()函數獲得機器內部計時器的時鐘頻率。接着在需要嚴格計時的事件發生前和發生之後分別調用QueryPerformanceCounter(),利用兩次獲得的計數之差和時鐘頻率,就可以計算出事件經歷的精確時間。


測試Sleep的精確時間:

#include <stdio.h>

#include <windows.h>

void main()

{

     LARGE_INTEGER nFreq;

     LARGE_INTEGER nBeginTime;

     LARGE_INTEGER nEndTime;

     double time;

 

     QueryPerformanceFrequency(&nFreq);

     QueryPerformanceCounter(&nBeginTime); 

 

     Sleep(1000);

 

     QueryPerformanceCounter(&nEndTime);

     time=(double)(nEndTime.QuadPart-nBeginTime.QuadPart)/(double)nFreq.QuadPart;

 

     printf("%f\n",time);

     Sleep(1000);

system("Pause");

}

結果爲

0.999982

1.000088

1.000200

等,所以Sleep的精度還是比較低的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章