10
votes

Inside the static Stopwatch constructor we can see the following code, that basicly checks whether a high-resolution performance counter exists.

static Stopwatch()
{
    if (!SafeNativeMethods.QueryPerformanceFrequency(out Frequency))
    {
        IsHighResolution = false;
        Frequency = 0x989680L;
        tickFrequency = 1.0;
    }
    else
    {
        IsHighResolution = true;
        tickFrequency = 10000000.0;
        tickFrequency /= (double) Frequency;
    }
}

On MSDN it says about QueryPerformanceFrequency:

Retrieves the frequency of the high-resolution performance counter, if one exists

It's pretty unclear, however, when exactly does it exist? I suspect it usually exists on current machines, but when exactly doesn't it?

It's interesting because when it doesn't exist, Stopwatch becomes a mere wrapper around the DateTime.UtcNow property.

2
I've not come across a machine were it doesn't exist yet. The main practical problem I've faces are the bugs in its behavior caused by buggy hardware. For example the time can jump forward/backward as the thread gets scheduled on different cores,..CodesInChaos
It is optional in Windows Mobile, up to the platform builder to implement it.Hans Passant
The "IsHighResolution" and "Frequency" properties of this class should answer this question. Note:I found a frequency of zero in a virtual machine [VMWare ESX, but don't remember the version] which do no longer appear [the machine was migrated from w2k3 to w2k8, so it could have been VMWare or Windows :-) ] br++mabramabra

2 Answers

5
votes

There is a difference between a timer and a stopwatch, and confusing the two leads to erroneous assumptions. Unfortunately, the term timer is used to mean multiple things all too often.

Any machine that runs Windows 2000 or later likely has a high frequency timer. I have never run across a computer that runs Windows 2000 later that does not have such a thing.

Now, that's the high frequency timer. There are also timers: Windows or .NET components. These timers are not used for keeping time or for measuring time, but rather for performing actions at periodic intervals. The Windows timer objects are capable of 1 ms resolution, and are very reliable when the computer is not involved in CPU intensive operations. The .NET timer objects are limited to approximately 15 ms resolution. You can get around that by using P/Invoke to interact directly with the Windows objects, but it's not often necessary.

The .NET Stopwatch class is based on the high frequency timer. In general, Start queries the performance counter and stores the value. When you Stop, it queries the performance counter again. The elapsed time is a simple subtraction of those two values. You can get better than microsecond resolution from the Stopwatch.

And in fact, you can use a Stopwatch with a busy-waiting loop that gives you sub-millisecond resolution. I doubt that you could get sub-microsecond resolution with it.

The important thing to understand is that, although timers aren't reliable beyond 1 millisecond, the stopwatch, which measures elapsed time, is much more precise. You can probably trust microsecond-level elapsed time measurements from Stopwatch. Beyond that, I wouldn't count on it.

1
votes

Actual resolution of the system time is on the order of milliseconds (even though it is claimed to be 1/10th of a millisecond, I've never seen a workstation that provides that resolution reliably).

However, you can use additional hardware (like time code readers) which provides resolutions down to nanoseconds. These are usually used in industrial control systems in line with IPCs (industrial PCs) to synchronize DAQ hardware. You can see an example with 100 ns resolution in PCI Express Slot Cards. Time code processor for PCI express low-profile x1 local bus.

Ordinary workstations will almost always use high-resolution counters, but actually resolution will not be what you would expect (micro or nano seconds) without additional hardware.