Windows队列计时器的

Windows队列计时器的

本文介绍了Windows队列计时器的限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个计时器,需要它每50毫秒左右运行一次,并且希望分辨率为1毫秒或更短.我首先阅读了这两篇文章:

I am implementing a timer and need it to run every 50 ms or so and would like the resolution to be 1 ms or less. I started by reading these two articles:

http://www.codeproject.com/Articles/1236/Timers-Tutorial

http://www.virtualdub.org/blog/pivot/entry.php?id = 272

奇怪的是,它们似乎相互矛盾.有人说队列计时器适合高分辨率,另一篇文章则来自Windows 7系统,结果显示分辨率约为15ms(对于我的应用程序来说还不够好).

Oddly enough they seem to contradict one another. One says queue timers are good for high resolution, the other posts results from a Windows 7 system showing resolution around 15ms (not good enough for my application).

因此,我在系统(Win7 64位i7-4770 CPU @ 3.4 Ghz)上进行了测试.我开始的时间是50毫秒,这就是我所看到的(从左开始的时间,右执行之间的时间;以毫秒为单位):

So I ran a test on my system (Win7 64bit i7-4770 CPU @3.4 Ghz). I started at a period of 50ms and this is what I see (time since beginning on left, gap between executions on right; all in ms):

150   50.00
200   50.01
250   50.00
...
450   49.93
500   50.00
550   50.03
...
2250  50.10
2300  50.01

我看到最大误差约为100 us,平均误差可能约为30 us.这让我很高兴.

I see that the maximum error is about 100 us and that the average error is probably around 30 us or so. This makes me fairly happy.

因此,我开始删除句点,以查看它在什么时候变得不可靠.缩短周期< = 5毫秒后,我开始看到不好的结果.

So I started dropping the period to see at what point it gets unreliable. I started seeing bad results once I decreased the period <= 5ms.

在5ms的周期内,有些周期每隔几秒钟会在3ms和6ms之间跳跃是很常见的.如果我将周期减少到1ms,则可以看到5到10到40毫秒的周期.我想跳到40毫秒可能是由于我将东西打印到屏幕上,我不知道.

With a period of 5ms it was not uncommon to see some periods jump between 3 and 6ms every few seconds. If I reduce the period to 1ms periods of 5 to 10 to 40 ms can be seen. I presume that the jumps up to 40ms may be due to the fact that I'm printing stuff to the screen, I dunno.

这是我的计时器回调代码:

This is my timer callback code:

VOID CALLBACK timer_execute(PVOID p_parameter,
   BOOLEAN p_timer_or_wait_fired)
{
   LARGE_INTEGER l_now_tick;

   QueryPerformanceCounter(&l_now_tick);

   double now = ((l_now_tick.QuadPart - d_start.QuadPart) * 1000000) / d_frequency.QuadPart;
   double us = ((l_now_tick.QuadPart - d_last_tick.QuadPart) * 1000000) / d_frequency.QuadPart;

   //printf("\n%.0f\t%.2f", now / 1000.0f, ms / 1000.0f);

   if (us > 2000 ||
       us < 100)
   {
      printf("\n%.2f", us / 1000.0f);
   }

   d_last_tick = l_now_tick;
}

无论如何,只要您以100hz或更慢的速度执行,队列计时器就好像是非常好的工具.我链接到的第二篇文章中发布的不良结果(精度为15ms左右)是否可能是由于CPU速度较慢或配置不同?

Anyways it looks to me as if queue timers are very good tools so long as you're executing at 100hz or slower. Are the bad results posted in the second article I linked to (accuracy of 15ms or so) possibly due to a slower CPU, or a different config?

我想知道是否可以在多台计算机上获得这种性能(与运行64位Win7的计算机一样快或更快)?另外,我注意到,如果您的回调在该时间段之前没有退出,则操作系统将在其中放置另一个线程.这也许很明显,但是它在任何文档中都对我并不突出,并且对客户端代码有重大影响.

I'm wondering if I can expect this kind of performance across multiple machines (all as fast or faster than my machine running 64bit Win7)? Also, I noticed that if your callback doesn't exit before the period elapsed, the OS will put another thread in there. This may be obvious, but it didn't stand out to me in any documentation and has significant implications for the client-code.

推荐答案

Windows默认计时器分辨率为15.625毫秒.那就是您观察到的粒度.但是,可以如MSDN所述修改系统计时器分辨率:获取和设置计时器分辨率.这样可以将大多数情况下的粒度降低到大约1毫秒平台. SO答案公开了如何获取当前系统计时器分辨率.

The Windows default timer resolution is 15.625 ms. That is the granularity you observe.However, the system timer resolution can be modified as described by MSDN: Obtaining and Setting Timer Resolution. This allows to reduce the granularity to about 1 ms on mostplatforms. This SO answer discloses how to obtain the current system timer resolution.

当平台支持时,隐藏功能NtSetTimerResolution(...)甚至允许将计时器分辨率设置为0.5 ms.请参阅这样的问题"如何将计时器分辨率设置为0.5 ms?"的答案

The hidden function NtSetTimerResolution(...) even allows to set the timer resolution to 0.5 ms when supported by the platform. See this SO answer to the question "How to setup timer resolution to 0.5 ms?"

...其他配置?它取决于基础硬件和操作系统版本.使用上述工具检查计时器分辨率.

...a different config?It depends on underlying hardware and OS version. Check the timer resolution with the tooles mentioned above.

...与运行64位Win7的计算机一样快还是更快?是的你可以.但是,还允许其他应用程序设置计时器分辨率.谷歌浏览器是一个著名的例子.这样的其他应用程序也可能仅临时更改计时器分辨率.因此,您永远不能依赖计时器分辨率跨平台/时间保持不变.确保计时器分辨率的唯一方法是由您的应用程序控制的是您自己将计时器粒度设置为至少1毫秒(0.5毫秒).

...all as fast or faster than my machine running 64bit Win7)?Yes you can. However, other applications are also allowed to set the timer resolution. Google Chrome is a known example. Such other application may also only temporarily change the timer resolution. Therefore you can never rely on the timer resolutionbeing a constant across platforms/time.The only way to be sure that the timer resolution iscontrolled by your application is to set the timer granularity to the minimum of 1 ms (0.5ms) by yourself.

注:减小系统计时器的粒度会导致系统中断频率增加.它减少了线程数量(时间片)并增加了功耗.

Note: Reducing the system timer granularity causes the systems interrupt frequency to increase. It reduces the thread quantum (time slice) and increases the power consumption.

这篇关于Windows队列计时器的限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 05:30