2014-01-16 37 views
2

我知道每個計時器的默認值爲15.6  毫秒,但有些輸家可能會改變它,然後一次又一次地來回改變,我需要查詢當前的電流值是執行有效的QueryPerformanceCounter同步。如何獲取當前Windows系統範圍內的計時器分辨率

那麼有沒有一種API方式來獲得計時器分辨率?

我在C++中順便說一句。

回答

10

的Windows計時器的分辨率是由隱藏API提供:

NTSTATUS NtQueryTimerResolution(OUT PULONG MinimumResolution, 
           OUT PULONG MaximumResolution, 
           OUT PULONG ActualResolution); 

NtQueryTimerResolution是由本地的Windows NT庫ntdll.dll輸出。

通用硬件平臺報告156,250或100,144 實際分辨率;舊平臺可能會報告更多的數據;較新的系統,特別是當支持HPET(高精度事件定時器)或恆定/不變TSC時,實際分辨率可能會返回156,001。

致電timeBeginPeriod(n)反映在實際分辨率

更多詳細情況在this解答。

+1

終於一個正確的答案。我也做了一個小的github項目,它在C#中用p/invoke實現了這個方法:https://github.com/tebjan/TimerTool – thalm

+0

應該注意的是,該工具只會建立一個新的定時器週期(_Begin Timer Period_ )當新值小於實際值時。當沒有其他進程建立_Current Period_的定時器週期時,_Timer結束週期_將僅起作用。附註:當前不一定在_Min_和_Max_的範圍內;例如以1024 interrups/s運行的系統顯示當前值:0,9766,最小值:15,625,最大值:1.這是由於'NtQueryTimerResolution'參數缺乏準確性。在[this](http://stackoverflow.com/a/11628374/1504523)答案中的更多詳細信息。 – Arno

0

WINAPI功能GetSystemTimeAdjustment

+0

不,不是。這是一個Windows時間修復解決方案。 – alemjerus

+0

第二個參數是「指向DWORD的指針,該函數在週期性時間調整之間設置間隔,以100納秒爲單位計數,該間隔是系統時鐘中斷之間的時間間隔。」 –

+0

你確定嗎?因爲邏輯表示,如果時間變化本身很小,它可能會在一小時左右。還有更多。時間調整可能會被禁用! – alemjerus

4

這會不會是有幫助的,另一個進程可以改變它要校準。

這屬於「如果你不能打敗他們,加入他們」類別。在開始校準之前撥打timeBeginPeriod(1)。這可確保您擁有無人可以更改的已知費率。獲得改進的計時器準確性並不會傷害任何一方。

請注意,您可能比QueryPerformanceFrequency()做得更好。除非您長時間校準很長時間,否則時鐘頻率不足以提供更高的準確度,因爲您永遠無法測量好於+/- 0.5毫秒。並且計時器事件沒有以毫秒級的精度傳遞,它可以任意延遲。如果長時間校準,那麼GetTickCount64()足夠好。

+0

我需要確切地知道在單個系統計時器時間週期中有多少個CPU滴答滴答才能與另一個同步。這給了ms〜300ns定時器分辨率。 – alemjerus

+0

「cpu ticks」是什麼意思? CPU有一個時鐘週期,運行在千兆赫茲。它在現代處理器上動態變化,並且與QueryPerformanceCounter或timeBeginPeriod沒有任何關係。 –

+0

好的,我的意思是:系統計時器中有多少個QPC滴答滴答。我知道默認值大約是47800,但即使系統計時器精度已更改,我也需要確保。如果我錯過了一次或兩次更改,無所謂,畢竟我要微秒。 – alemjerus

1

RDTSC指令可用於讀取CPU時間戳計數器。 在大多數情況下(如果不是全部),該計數器將以CPU時鐘頻率更改。 如果你想挑剔,你也可以使用像CPUID這樣的指令來序列化指令。 有關更多詳細信息,請參閱英特爾手冊。

您可以使用API​​的QueryPerformanceCounter等工作RDTSC。 換句話說,在通話之前和之後使用RDTSC進行測量。