Waitable timer accuracy
From: Revelation (anonymous_at_discussions.microsoft.com)
Date: 04/19/04
- Next message: David Lowndes: "Re: FileSystem Problem"
- Previous message: Mitesh Desai [MSFT]: "Re: [Q] TRacking down asserts by NdisTest"
- Next in thread: William DePalo [MVP VC++]: "Re: Waitable timer accuracy"
- Reply: William DePalo [MVP VC++]: "Re: Waitable timer accuracy"
- Messages sorted by: [ date ] [ thread ]
Date: Mon, 19 Apr 2004 16:11:02 -0700
Hi,
I'm working on a .NET wrapper for OpenGL and part of this project involves writing a multi-threaded rendering loop, which will include an option for frame rate throttling. For this, I time how long it takes to draw the scene and use a waitable timer to cause a delay if it was drawn too quickly. This worked out perfectly with the timer being precise enough to cause this sort of short delay, but for no apparent reason it seemed to lose accuracy from time to time and the frame rate would snap to values such as 50fps or 100fps, regardless of what I had set in the code.
After much frustration I tracked down the cause to be the waitable timer losing accuracy. When working normally, the timer is able to produce delays down to 1 millisecond, but when the behaviour starts to get eratic it appears that the timers minimum delay drops to 1 hundreth of a second. Now I know that the documentation states the accuracy of the timer is system dependant, but my system is clearly capable of 1ms delays when it chooses. I've had the chance to test my code on Windows 2000 and Windows 2003 on two different machines, and all show the same behaviour. Am I expecting too much from the timer objects? Is it normal for their accuracy to change? The stripped down code I used to test the timings is shown below (its written in C#).
using System;
using System.Runtime.InteropServices;
using System.Threading;
class SafeNativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] internal static extern bool SetWaitableTimer(IntPtr hTimer, ref long pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] internal static extern int WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] internal static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] internal static extern bool QueryPerformanceFrequency(out long lpFrequency);
}
class UnsafeNativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = false)] internal static extern IntPtr CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] internal static extern bool CloseHandle(IntPtr hObject);
}
class Program
{
static void Main(string[] args)
{
long frequency;
SafeNativeMethods.QueryPerformanceFrequency(out frequency);
IntPtr hTimer = UnsafeNativeMethods.CreateWaitableTimer(IntPtr.Zero, true, "MyTimer");
// Delay for the shortes possible time (in theory 1 nanosecond)
long dueTime = -1;
// Values used for the timing
long sum = 0, start, end;
// Get 100 timings and extract the average
for(int i = 0; i < 100; i++)
{
SafeNativeMethods.SetWaitableTimer(hTimer, ref dueTime, 0, IntPtr.Zero, IntPtr.Zero, false);
SafeNativeMethods.QueryPerformanceCounter(out start);
SafeNativeMethods.WaitForSingleObject(hTimer, -1);
SafeNativeMethods.QueryPerformanceCounter(out end);
sum += end - start;
}
UnsafeNativeMethods.CloseHandle(hTimer);
Console.WriteLine("Average delay: {0} seconds", (sum / 100d) / frequency);
// Pause before exit
Console.ReadLine();
}
}
- Next message: David Lowndes: "Re: FileSystem Problem"
- Previous message: Mitesh Desai [MSFT]: "Re: [Q] TRacking down asserts by NdisTest"
- Next in thread: William DePalo [MVP VC++]: "Re: Waitable timer accuracy"
- Reply: William DePalo [MVP VC++]: "Re: Waitable timer accuracy"
- Messages sorted by: [ date ] [ thread ]