IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Nanosecond Accuracy with QueryPerformanceCounter?

Thursday 31 March, 2005, 10:04 PM

Someone on the 'WinTech Off Topic' mailing list recently asked if it's possible to time things down to nanosecond level accuracy.

I wrote a response on the list, but I thought I'd expand on it here a little. (After all, I can't let all of March go by without a single blog post...)

The first thing to consider about the question is that at this sort of timescale, even if you do have access to a timer that accurate it's going to be really hard to interpret what your timings mean. Today, typical CPUs run in excess of 3GHz, so you'd think that 1ns accuracy shouldn't be that big a deal - it's three clock cycles right? But remember that CPU pipelines tend to run pretty deep these days. So while your processor might be able to execute instructions at a rate of several per nanosecond, that doesn't mean that any individual instruction necessarily executes in under a nanosecond.

The CPU typically has an awful lot of instructions on the go at once all at various different stages of processing. There's a pretty good chance that any given instruction took more than a nanosecond between starting to execute and being completely executed. In fact it's kind of hard to pin down, because it's not all that obvious when the 'start' and 'end' are. You could take the relatively straightforward-sounding idea that an instruction starts executing no sooner than the latest point in time at which changes elsewhere in the system can influence its outcome, and finishes executing no later than the earliest point in time after which all of its effects have become visible throughout the system. But that can turn out to be remarkably conservative, because you start getting into cache coherency issues.

Suffice it to say that the effective footprint in time of a single instruction is likely to be significantly more than a nanosecond.

So writing code to take measurements is going to introduce a few nanoseconds of uncertainty into the equation before you start.

But that aside, do we even have timers available with that kind of accuracy available? And the answer is: probably. Any reasonably modern machine will. As someone on the OT list pointed out, it'll be accessible through the QueryPerformanceCounter API. You can discover the frequency at which this counter runs on your particular system with QueryPerformanceFrequency.

These will give you pretty high resolution timing facilities. However, there is no guarantee about what the actual accuracy will be.

More alarmingly, there turns out to be no guarantee that you won't experience bizarre time warp effects - power management on laptops of a certain age cause the rate at which time appears to flow according to this APIs to vary!

If you can choose which hardware you'll be running on then, these APIs are likely to be fine. But if you want to be able to use them on anything, there are a couple of things you need to be aware of:

If you're running on sufficiently old hardware (or a sufficiently old version of Windows) these APIs use as their timing reference the old programmable timer chip (the 8254?) that has been part of the PC architecture since the original IBM PC all those decades ago. (Of course it hasn't really been a seperate chip for some years now... It's built into the chipset. But it still acts like the old discrete timer chip that used to be there.)

In this case the tick frequency will be 1.19318MHz. This means that the accuracy of the timer is on the order of a microsecond, some three orders of magnitude short of the 'nanosecond' requirement. Also, be aware that reading this timer is pretty expensive.

Around a decade ago, Intel decided to build in a tick counter to their Pentium processors. So any moderately recent PC and recent version of Windows will use this instead. The tick counter frequency is related to the processor clock frequency. This gives you much better resolution than the old 8254-based timings,

However, on certain mobile processors the tick frequency is not constant. For example, on the Pentium III-M with SpeedStep, the frequency of the tick count would vary wildly as the CPU went into and out of various power management states. The only way to get consistent measurements was to turn off power management!

I'm not sure if recent versions of Windows are aware of this, and adjust the results from these APIs. But there was a time when they didn't, and for all I know they still don't.

More recently, a common frequency you'll see is 3.579545MHz. This turns out to come from the ACPI chipset. (Thanks to Jeroen Frijters to pointing me at this site for this detail.) This of course is also well short of 'nanosecond' accuracy.

So be careful out there...

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk