2010-06-29 1059 views
4

我想將機器定時器分辨率設置爲0.5ms。如何將計時器分辨率設置爲0.5 ms?

Sysinternal utility報告最小時鐘分辨率是0.5ms,因此可以完成。

P.S.我知道如何將它設置爲1ms。

P.P.S.我改變了它從C#到更一般的問題(由於漢斯)

系統計時器分辨率

+0

,你可以看看[這裏](HTTP://www.windowstimestamp/description)有關定時器設置和亞毫秒計時服務的詳細信息。 – Arno 2012-08-01 07:44:57

回答

7

NtSetTimerResolution

示例代碼:

#include <windows.h> 

extern "C" NTSYSAPI NTSTATUS NTAPI NtSetTimerResolution(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution); 

... 

ULONG currentRes; 
NtSetTimerResolution(5000, TRUE, &currentRes); 

鏈路與ntdll.lib

-6

Timer.Interval = 500;

+3

這是0.5秒.... – SRKX 2010-06-29 14:26:56

+1

這是半秒鐘。 OP要求小於1毫秒。 – bentsai 2010-06-29 14:27:01

1

你需要爲它高分辨率定時器..你可以在這裏找到一些信息:http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx

編輯:更多的信息可以在這裏找到:設置爲毫秒的十分之一; http://msdn.microsoft.com/en-us/library/aa964692(VS.80).aspx

+6

在System.dll中被「System.Diagnostics.Stopwatch」取代。 – 2010-06-29 14:36:59

+0

@Charlie Salts:那是Bobb正在尋找的我猜(+1) – riffnl 2010-06-29 14:41:13

+1

我不想測量時間,我只是需要它更快地打勾。 – 2010-06-29 20:30:27

3

您可以通過timeBeginPeriod和timeSetEvent獲得Win32 API的最佳時間爲1毫秒。也許你的HAL可以做得更好,但這是學術性的,你不能用C#編寫設備驅動程序代碼。

+0

我alredy使用這些。我希望能得到那個。你知道是否有一個實用程序可以做到這一點(在C#中不是必然的)。畢竟,我只需要改變系統時鐘。 – 2010-06-29 20:33:16

+0

我從C#更改爲其他任何東西。無論如何只需要這樣做。 – 2010-06-29 20:35:40

3

可能通過隱藏API NtSetTimerResolution()獲得0.5 ms分辨率。 NtSetTimerResolution由本機Windows NT庫NTDLL.DLL導出。請參閱MSDN上的How to set timer resolution to 0.5ms ?。不過,真正可實現的解決方案是由底層硬件決定的。現代硬件支持0.5毫秒的分辨率。 更多詳情請見Inside Windows NT High Resolution Timers。支持的分辨率可以通過調用NtQueryTimerResolution()來獲得。

怎麼做:

#define STATUS_SUCCESS 0 
#define STATUS_TIMER_RESOLUTION_NOT_SET 0xC0000245 

// after loading NtSetTimerResolution from ntdll.dll: 

// The requested resolution in 100 ns units: 
ULONG DesiredResolution = 5000; 
// Note: The supported resolutions can be obtained by a call to NtQueryTimerResolution() 

ULONG CurrentResolution = 0; 

// 1. Requesting a higher resolution 
// Note: This call is similar to timeBeginPeriod. 
// However, it to to specify the resolution in 100 ns units. 
if (NtSetTimerResolution(DesiredResolution ,TRUE,&CurrentResolution) != STATUS_SUCCESS) { 
    // The call has failed 
} 

printf("CurrentResolution [100 ns units]: %d\n",CurrentResolution); 
// this will show 5000 on more modern platforms (0.5ms!) 

//  do your stuff here at 0.5 ms timer resolution 

// 2. Releasing the requested resolution 
// Note: This call is similar to timeEndPeriod 
switch (NtSetTimerResolution(DesiredResolution ,FALSE,&CurrentResolution) { 
    case STATUS_SUCCESS: 
     printf("The current resolution has returned to %d [100 ns units]\n",CurrentResolution); 
     break; 
    case STATUS_TIMER_RESOLUTION_NOT_SET: 
     printf("The requested resolution was not set\n"); 
     // the resolution can only return to a previous value by means of FALSE 
     // when the current resolution was set by this application  
     break; 
    default: 
     // The call has failed 

} 

注:NtSetTImerResolution的功能是通過使用布爾值Set基本上映射到功能timeBeginPeriodtimeEndPeriod(見Inside Windows NT High Resolution Timers有關該計劃的更多細節,所有的影響)。但是,多媒體套件將粒度限制爲毫秒,NtSetTimerResolution允許設置亞毫秒值。

+0

謝謝。那是我4年前發現的......但是自從敵意和誤導的答案發作以來,我自己回答了這個問題,但儘可能短(因爲沒有人需要這樣做)。我很高興在我的實時軟件中使用它(根據大多數'開發人員',這是不可能在windows和.net上編寫的)。PS我看着你的項目。看起來很有希望..只是看着窗戶計時器'抖動'..你的項目比我的更具挑戰性!祝你好運! – 2014-04-05 18:47:07

+0

根據我的實驗,我認爲STATUS_TIMER_RESOLUTION_NOT_SET錯誤代碼應該是0xC0000245而不是245 – 2014-04-26 22:46:57

+0

@RolandPihlakas這是正確的,謝謝。我編輯了我的答案,以糾正此問題。它實際上[記錄在MSDN](http://msdn.microsoft.com/en-us/library/cc704588.aspx)就是這樣。 – Arno 2014-04-27 09:28:02

0

如果您使用python,我寫了一個名爲wres的庫,它在內部調用NtSetTimerResolution。

pip install wres

import wres 

# Set resolution to 0.5 ms (in 100-ns units) 
# Automatically restore previous resolution when exit with statement 
with wres.set_resolution(5000): 
    pass 
+0

也許在這篇文章中增加更多的細節對OP和整個社區來說會更有幫助。 – 2017-03-30 12:49:54