windows 如何将计时器分辨率设置为 0.5 毫秒?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3141556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:44:02  来源:igfitidea点击:

How to setup timer resolution to 0.5 ms?

c++windowswinapitimerdriver

提问by Boppity Bop

I want to set a machine timer resolution to 0.5ms.

我想将机器计时器分辨率设置为 0.5ms。

Sysinternal utility reports that the min clock resolution is 0.5ms so it can be done.

Sysinternal 实用程序报告最小时钟分辨率为 0.5 毫秒,因此可以完成。

P.S. I know how to set it to 1ms.

PS我知道如何将其设置为1ms。

P.P.S. I changed it from C# to more general question (thanks to Hans)

PPS 我将它从 C# 改为更一般的问题(感谢 Hans)

System timer resolution

系统定时器分辨率

回答by Boppity Bop

NtSetTimerResolution

NtSetTimerResolution

Example code:

示例代码:

#include <windows.h>

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

...

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

Link with ntdll.lib.

与 链接ntdll.lib

回答by Arno

You may obtain 0.5 msresolution by means of the hidden API NtSetTimerResolution(). NtSetTimerResolution is exported by the native Windows NT library NTDLL.DLL. See How to set timer resolution to 0.5ms ?on MSDN. Nevertheless, the true achievable resoltion is determined by the underlying hardware. Modern hardware does support 0.5 ms resolution. Even more details are found in Inside Windows NT High Resolution Timers. The supported resolutions can be obtained by a call to NtQueryTimerResolution().

可以通过隐藏的 API获得 0.5 毫秒的分辨率NtSetTimerResolution()。NtSetTimerResolution 由本机 Windows NT 库 NTDLL.DLL 导出。请参阅如何将计时器分辨率设置为 0.5 毫秒?在 MSDN 上。然而,真正可实现的分辨率是由底层硬件决定的。现代硬件确实支持 0.5 毫秒的分辨率。更多细节可以在Inside Windows NT High Resolution Timers 中找到。可以通过调用 NtQueryTimerResolution() 获得支持的分辨率。

How to do:

怎么做:

#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

}

Note: The functionality of NtSetTImerResolution is basically mapped to the functions timeBeginPeriodandtimeEndPeriodby using the bool value Set(see Inside Windows NT High Resolution Timersfor more details about the scheme and all its implications). However, the multimedia suite limits the granularity to milliseconds and NtSetTimerResolution allows to set sub-millisecond values.

注意:NtSetTImerResolution 的功能基本上映射到函数timeBeginPeriodtimeEndPeriod使用 bool 值Set(有关该方案及其所有含义的更多详细信息,请参阅Windows NT 高分辨率计时器内部)。但是,多媒体套件将粒度限制为毫秒,并且 NtSetTimerResolution 允许设置亚毫秒值。

回答by Hans Passant

The best you can get out the Win32 API is one millisecond with timeBeginPeriod and timeSetEvent. Maybe your HAL can do better but that's academic, you cannot write device driver code in C#.

最好的 Win32 API 是带 timeBeginPeriod 和 timeSetEvent 的一毫秒。也许你的 HAL 可以做得更好,但这是学术性的,你不能用 C# 编写设备驱动程序代码。

回答by jks Liu

If you use python, I wrote a library named wres, which calls NtSetTimerResolution internally.

如果你使用 python,我写了一个名为wres的库,它在内部调用 NtSetTimerResolution。

pip install wres

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

回答by riffnl

You'll need a high resolution timer for it.. You can find some information here: http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx

你需要一个高分辨率的计时器。你可以在这里找到一些信息:http: //www.codeproject.com/KB/cs/highperformancetimercshar.aspx

EDIT: More information can be found here: set to tenth of millisecond; http://msdn.microsoft.com/en-us/library/aa964692(VS.80).aspx

编辑:可以在此处找到更多信息:设置为毫秒的十分之一;http://msdn.microsoft.com/en-us/library/aa964692(VS.80).aspx