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
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).
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
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.
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.
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;
}
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?
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.