gw_logo_08.gif (1982 bytes) 
Last edit: 05-03-17 Graham Wideman
Data Acquisition
Precision Timing Under Windows Operating Systems
Article created: 99-06-16


This page collects and summarizes material that I've found relating to strategies for performing precision timing tasks under Windows 32-bit OSes.  These topics include:

Reading the Time

Time-of-Day functions are provided by most language environments.  These are generally based on the OS's time-of-day functions, which derive from an interrupt mechanism that's set to occur on at an interval of about 55 millisec, or 18.2/sec.   (Why the strange number? Because it's 1 hour divided by 2^16, or 1/65536 hour.)   Needless to say, calling these functions hardly classifies as "precision timing".

A more satisfactory source of time information is the set of Windows API functions that provide for reading the system's precision timing source. These include:

This sounds fantastic, except that Windows may not be running your process or thread when the event occurs that you are trying to time... so you have to know about the multitasking issues to understand what you can realistically expect.

Scheduling Service Routines

This is the really important part of the puzzle -- how to have your routines invoked at a particular time.  Two main techniques are available, though ultimately they depend on the same Windows scheduling mechanism for their operation.

timeSetEvent (and related functions): This allows a program to tell the OS task scheduler that it wants a callback to a particular function, after N millisecs, or at N millisec intervals.

Thread Sleep: Allows a program to put a thread to sleep for N milliseconds.

Both of these approaches seem to provide the needed functionality but both are subject to additional delay if they are not the highest priority task at the callback or awaken time.  The priority is a combination of the process (application) priority and the individual thread priority. See other pages on this site for details on multitasking, process and thread priority, and also see my LabVIEW pages for a study of typical delays that preempt the kind of timing procedures described here.

Note that if you are going to use either approach, you'll want to know about Scheduler Resolution... see the Multitasking Discussion page -- particularly the Scheduler Granularity discussion.

The 16-bit DLL Technique:  According to several of the sources listed below, timing under Win3.1 was significantly more precise than under Win95/98 and NT. This leads to the suggestion that one way to get more precise timing under Win95 is to use a 16-bit DLL to handle time-critical scheduled tasks. This is described in the Overcoming Timer Latency reference below.  A couple of cautions:   This looks pretty hairy, and it's also not applicable to NT.  I'd be interested to hear further details of how this method turns out in practice, whether it really manages to displace Win95's scheduler, and whether it works in Win98.  I'm assuming it won't be supported in Win2000.
 [Update 2000-03-24: See comments below from Thiadmer Riemersma]

References and Comments

Note: Websites often move their documents around.  If you find that a link is broken, try copying the document title into a search engine like AltaVista to find a new location or alternate copy somewhere.

Ryle Design Homepage

First mention goes to Tom Leathley of Ryle Design, just because I've used his timing routines since 1990, and they have done such good service. His current products include ExacTicks timing components for Windows, and features a thorough manual explaining a number of timing issues for the various Windows OSes.  The product also includes source code, so if you think you need to get directly at the Windows API functions you can see how fully working code does it.

The Problems You're Having May Not Be the Problems You Think You're Having: Results from a Latency Study of Windows NT
Michael B. Jones,  Microsoft Research
John Regehr, Department of Computer Science, University of Virginia
March 1999

This paper is intended to catalyze discussions on two intertwined systems topics. First, it presents early results from a latency study of Windows NT that identifies some specific causes of long thread scheduling latencies, many of which delay the dispatching of runnable threads for tens of milliseconds. Reasons for these delays, including technical, methodological, and economic are presented and possible solutions are discussed.

Secondly, and equally importantly, it is intended to serve as a cautionary tale against believing one's own intuition about the causes of poor system performance. We went into this study believing we understood a number of the causes of these delays, with our beliefs informed more by conventional wisdom and hunches than data. In nearly all cases the reasons we discovered via instrumentation and measurement surprised us. In fact, some directly contradicted "facts" we thought we "knew".

My comments:   Of the sources I found, this one probably presents the clearest thinking on the subject  Highly Recommended!

Issues in Using Commodity Operating Systems for Time-Dependent Tasks
Michael B. Jones,  Microsoft Research
John Regehr, Department of Computer Science, University of Virginia

This paper presents a snapshot of early results from a study of Windows NT aimed at understanding and improving its limitations when used for time-dependent tasks, such as those that arise for audio and video processing.

Clearly there are time scales for which it can achieve effectively perfect reliability, such as the one-second deadlines present in the Tiger Video Filesystem. Other time scales, such as reliable sub-millisecond scheduling of periodic tasks in user space, are clearly out of reach. Yet, there is an interesting middle ground between these time scales in which deadlines may be met, but will not always be.

My comments:   More from the same authors as The Problems You're Having

Overcoming Timer-Latency Problems in MIDI Sequencers 
Mark McCulley, Microsoft Corporation, February 23, 1996

MIDI sequencer applications require extremely precise timer services. Occasionally applications experience a delay in receiving notification from a timer—this delay is called timer latency. Timer latency under Microsoft® Windows® 95 can be considerably greater than under Windows 3.1 and can result in audible glitches when playing MIDI files with Win32®-based MIDI sequencers. In this article, I present a technique to minimize timer latency under Windows 95. This technique can be applied in MIDI sequencers as well as in other applications sensitive to timer latency.

Among the techniques described: Under Win95 use a 16-bit dll. Not applicable to NT.

My comments:  Since this document appears in the MS Developer Network area of MS's site, and is refered to by other docs on the MS site, it might be taken as somewhat authoritative.  However, some of it is acknowledged to be a bit speculative:

Windows NT does not allow you to use 16-bit DLLs with your 32-bit application. Fortunately, based on my observations using the Latency sample application, you don't need to—multimedia timers in Windows NT are the steadiest of any setup I tested. I should post a disclaimer here: My testing was limited and unscientific.

My testing, detailed in LabVIEW pages on this site, indicates that timing is still a significant issue on NT.

Moving Your Game to Windows, Part I:  Tools, Game Loop, Keyboard Input, and Timing
Peter Donnelly, Microsoft Developer Network Technology Group, September 26, 1996

This first article will concentrate on two of the most fundamental issues confronting you as a designer of real-time games: building the main game loop—the engine that drives the action—and timing events so that things proceed at a pace chosen by you rather than by the hardware or operating system.

A Comparison of Windows Driver Model Latency Performance on Windows NT and Windows 98
Erik Cota-Robles, James P. Held, Intel Architecture Labs

Windows† 98 and NT† share a common driver model known as WDM‡ [...] We compare the performance of Windows 98 and Windows NT 4.0 under load from office, multimedia and engineering applications on a personal computer (PC) of modest power that is free of legacy hardware. We report our observations using a complementary pair of system performance measures, interrupt and thread latency, that capture the ability of the OS to support multimedia and real-time workloads in a way that traditional throughput-based performance measures miss.

Test Report Millisecond Resolution Timing With Visual C++ and Windows 95
Chih-Hao Tsai, University of Illinois at Urbana-Champaign, 3/8/1998

Two run-time library functions and two Win32 API functions from Microsoft Visual C++ Version 4.0 were tested on a Windows 95 machine with a standardized procedure for their quality (in terms of the resolution they can achieve).

My critique: The test results presented are from a limited number of samples, and are apt to miss the kinds of infrequent but significant interruptions that occur in a multitasking environment.  Nonetheless, these results do demonstrate that the multimedia timers are not 100% reliable.

Inside Windows NT High Resolution Timers
System Internals: Mark Russinovich Last Updated July 9, 1997

This article describes how high resolution timers are implemented in NT and documents NtSetTimerResolution and NtQueryTimerResolution, the NT kernel functions that manipulate and return information about the system clock.

I've often found System Internals docs to be deep and thorough, and that's the case here too. The only puzzle was their description of the scheduler quantum, which appears to conflict with what testing shows (see my Multitasking Discussion page).

Making Windows NT a Real-Time Solution - A Technical Overview
Sam Dekey, National Instruments

Although Windows NT is not designed for hard real-time applications, you can use a variety of the techniques we discuss in this paper to achieve better real-time performance from Windows NT. [...]  Moreover, the design of Windows NT includes enough RTOS elements (such as a priority-driven, preemptive scheduler) to make it a viable choice for building real-time applications. We discuss the design of Windows NT as it relates to the elements of an RTOS. We include practical tips on how to take advantage of the design and the features of Windows NT for fine-tuning real-time applications.

I personally found some of the "practical tips" to be more like arguments about why you are likely to be unsatisfied with NT, and may need to go to something more robust, like add-on hardware such as LabVIEW RT.  You can get the pdf article here.

Regarding "The 16-bit DLL Technique"...
Thiadmer Riemersma, 2000-03-24 writes...

I experimented with this technique so I may clarify some issues.

In Win95, the 16-bit multimedia timer callbacks are called (indirectly) on an interrupt. The timing is indeed a lot more stable than that of 32-bit callbacks in Win95.

It works well in the sense that the callback gets called at a fairly reliable interval. But, being called from an interrupt also means that you have to cope with re-entrancy. Win95 is not re-entrant for the biggest part and neither is DOS (on which Win95 is based), nor most of the Windows drivers. So there is hardly anything you can do in the callback. The one (peculiar?) exception is for low level MIDI driver calls: these are required to be re-entrant.

Yes. [ it works in Win98.]  It is indeed not supported in Win2000.

[Regarding SkedGran results seeming to conflict with System Internals docs...]

Strange indeed. When I ran with SkedGran, I got a granularity of 5 ms (with normal timing), but this was running on Win95. Testing on WindowsNT gave me 10 ms (normal timing), which is in accordance with your description. I tried running a heavy task in the background (which would eat up most of the time) and I monitored with a task/thread viewer. The only thing I saw is that the SkedGran thread that sleeps gets a high priority. From the source code, I assume that you did this on purpose; in any case it does not negate your conclusions.

Thiadmer Riemersma
Animation tools for programmers, contract programming

[Up to:  Data Acquisition Topics]

Go to:  gw_logo_08.gif (1982 bytes)