Sunday, October 15, 2006

SetTimer granularity problem, and multimedia alternative

SetTimer's granularity is 10 ms in w2k, and 15.625 ms in XP. As the following data shows, w2k can achieve exactly 25 Hz, but in XP the best fit is 21.33 Hz. Neither OS can achieve 30 Hz, and worse yet, they fail differently: a period of 33 ms gets you 25 Hz in w2k, and 21.33 Hz in XP.

available fequencies (w2k):
period 1..10 11..20 21..30 31..40 41..50 51..60
freq 100 50 33.33 25 20 16.67

available fequencies (XP):
period 1..15 16..31 32..46 47..62 63..78 79..93
freq 64 32 21.33 16 12.8 10.67

Note: in XP, weird behavior occurs near the above boundaries, e.g. at period = 31, freq oscillates between 31.03 and 30.52.

Multimedia timers appear to have 1 ms granularity, but are significantly more expensive in terms of CPU load. Note that that the callback runs in a system thread and must not post timer messages while OnTimer is running; otherwise if OnTimer consumes more than one timer period's worth of CPU time, the GUI will be non-responsive.

volatile BOOL m_InTimer; // true if we're in OnTimer
static void CALLBACK MMTimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
if (!m_InTimer)
PostMessage((HWND)dwUser, WM_TIMER, 0, 0);
}

No comments: