Dispelling the myths, rumors, and innuendo surrounding the QueryPerformanceCounter function


The Query­Performance­Counter function has been the subject of much rumor and innuendo. In response to all the confusion, the kernel folks put together a page which tries to settle the controversy once and for all. It discusses the history of QPC over the ages, the problems it had on earlier versions of Windows or older firmware (which is probably where a lot of the myths started), its interaction with hypervisors, offers guidance on how to use it and its alternatives, and includes a very nice Q&A.

Comments (28)
  1. WndSks says:

    "QPC was introduced in Windows 2000 and Windows XP …" wayback.archive.org/…/QueryPerformanceCounter.asp says Windows NT 3.1. How am I supposed to trust the rest of this document when it starts off this way?

    [MSDN gradually loses its memory of products that are no longer in support. This makes sense in that you don't want MSDN to tell you about potential behaviors that no longer apply (imagine if Interlocked­Increment still documented the old behavior where it only returned the sign of the result), but it makes articles about history feel odd. (I guess the article in question could have started with "Versions of Windows prior to Windows 2000 are not covered by this article.") -Raymond]
  2. OldFart says:

    Interesting article.  I like this new GetSystemTimePreciseAsFileTime function.  I wonder how much argument went into deciding where to insert the word "Precise" in the function name.

  3. alegr1 says:

    First they fudged GetSystemTime functions by letting the clock correction to move time back. Now they invented the new function instead of fixing the old one.

  4. UseSmallIcons says:

    @alegr1

    They couldn't fix the old one because there will already be people relying on how it currently works. Once it's out there, removing it or changing it's behaviour is something that is very hard to do, regardless of whether or not the current behaviour is "broken".

  5. Michael Kohne says:

    Nice! I'm glad they cleared all that up, it's been a long time coming.

  6. Joshua says:

    [MSDN gradually loses its memory of products that are no longer in support.]

    Since offline manuals have fallen out of use, I foresee a problem in the future where documentation for Vista cannot be obtained.

  7. Deduplicator says:

    Regarding "MSDN gradually loses its memory of products that are no longer in support."

    In limited ways, that might make sense. But please do not make it gratuitiously hard on people searching for info on dated platforms, for example because they have to / finally are allowed to migrate some sources to the new OS.

    Capping the introduced-in to the oldest still supported platform means that information is simply wrong.

    Removing the details how the unsupported older version differed makes sense, but at least allude to it with a blanket "versions prior to X had different behavior" where applicable. For bonus points, link to an older version which has those details (MSDN accumulates slightly different versions of all kind of documentation anyway, lets make that somewhat useful).

  8. Wear says:

    @Deduplicator It's not wrong if you look at it from the MSDN point of view. Basically they're taking the position that unsupported versions of the software outright don't exist and never did. So it's true that they were introduced in those versions because there are no prior versions.

    It's like that thing in the Wing Commander movie where they don't acknowledge pilots that have died.

  9. dbacher says:

    If I recall correctly — the API was added for either Video for Windows or the Multimedia extensions as part of Windows 3.1/3.11wg, because you needed a higher resolution timer than WM_TIMER or the 18.2hz timer for those purposes.  Typically you were decoding the video frames as quickly as you could, and using some combination of WM_USER and Invalidate that I don't recall right off the top of my head.  Or at least, that's how it worked in the code that I worked with — which typically used two DIBs for the buffers and tried to treat it like a DOS-mode VGA then.

    The article might start at that point because that's when kernel took over responsibility for it, though.  That would be consistent with the Windows 2000 time frame.  But the API was available before that, and so saying "was introduced in" is probably the part that is flawed.

  10. SimonRev says:

    @Dave, your description sounds a bit more like the multimedia timer (timeSetEvent and  timeGetTime) than the Query­Performance­Counter

  11. Greg M says:

    "Capping the introduced-in to the oldest still supported platform means that information is simply wrong."

    While that's true, it doesn't say "introduced-in", it says "Minimum Supported", and those OSes aren't supported any more.  That doesn't make it incredibly helpful, but it's not as outright wrong as "introduced-in".

  12. Ben Voigt says:

    @GregM: In this particular case, it does say "introduced in".  You're right that moving the goalpost for "Minimum Supported" isn't outright false, just confusing because of the multiple meanings of "supported".  But the sentence under discussion here is false.

    Similarly, mentions of pre-2000 versions could still have been avoided without making a flatly false statement by saying "has been available since Windows 2000" (true but potentially misleading).

  13. Tim! says:

    @Greg M: It does say "introduced in": just after the first header "QPC support in Windows versions".  I don't see "Minimum Supported".  I think you're looking at a different page than the one Raymond linked.

  14. Greg M says:

    I was looking at the MSDN page for the function, not the discussion page.  The article is in fact completely wrong.  :)

  15. Alwaze Leery says:

    Q: "How do I determine and validate that QPC works on my machine? "

    A: "You don't need to perform such checks."

    What a great answer!  

  16. Azarien says:

    "All computers that shipped with Windows Vista and Windows Server 2008 used a platform counter"

    Umm, but what about a computer that shipped with older version of Windows and was later upgraded?

    So this cannot be relied upon.

    [The upgrade would have failed with "Sorry, your computer cannot run Windows Vista." In the same way that all computers that shipped with Windows 8 support SSE2. -Raymond]
  17. Joshua says:

    [In the same way that all computers that shipped with Windows 8 support SSE2. -Raymond]

    Having seen some W8 errors for unsupported hardware, I'd say that much improvement in that area is needed.

    The bootstrapper doesn't check for most things and kernel bluescreens on boot with a nonsensical error message. (Not possible to change config on the setup CD to disable the "friendly" messages and read off the actual codes.)

    For that matter the change in W8.1 is really obnoxious in that it doesn't have the module offset address anymore. I'm sure you think the module offset address is worthless to the consumer. Not so. A Google search for the two codes one after the other has a pretty good chance of finding forum posts of others having the same problem with a good chance of potential solutions or explanations.

  18. yuhong2 says:

    [The upgrade would have failed with "Sorry, your computer cannot run Windows Vista." In the same way that all computers that shipped with Windows 8 support SSE2. -Raymond]

    Then it should say "runs", not "shipped with".

    [If the only things people can complain about are minor editing issues, then I guess this means that the article is pretty good. -Raymond]
  19. Deduplicator says:

    @Raymond: Ah, but we can always disagree with them being minor ;-)

    And for those poor souls having to support software on / migrate from ms-unsupported legacy-systems, they certainly aren't.

    Just yesterday heard someone curse about having to learn COBOL for a production-system, which is expected to still run in a decade…

  20. Klimax says:

    "All computers that shipped with Windows Vista and Windows Server 2008 used a platform counter"

    Umm, but what about a computer that shipped with older version of Windows and was later upgraded?

    So this cannot be relied upon.

    [The upgrade would have failed with "Sorry, your computer cannot run Windows Vista." In the same way that all computers that shipped with Windows 8 support SSE2. -Raymond]

    Interesting. Windows 7 will install on Pentium II/III machine. (440BX chipset) Might be interesting what source is in use…

  21. Joshua says:

    @Klimax: "Interesting. Windows 7 will install on Pentium II/III machine. (440BX chipset) Might be interesting what source is in use…"

    None. The logic probably goes "Oh only one care. I can use RDTSC instruction unsynced."

  22. yuhong2 says:

    @Klimax: According to the article it would be the ACPI PMT.

  23. voo says:

    @Yuhong Bao: I doubt that – the rtdsc instruction is by definition invariant on a system with one core, no frequency changes and no out of order execution (remember the good old time when cpus were oh so very simple?)

  24. smf says:

    I wonder how many people use this and what problems they come up against.

    forums.mydigitallife.info/…/46840-Windows-8-CPU-Feature-Patch-(Bypass-Windows-8-CPU-feature-checks)

  25. fms says:

    @smf, Years ago I installed W98 on a Cyrix CPU (maybe something else, some other exotic chip). That chip didn't support the CMPXCHG instruction, and so the installer refused.

    To bypass that I started installation on another box, and on the first reboot I put the harddisk in the Cyrix box. I cannot recall to have had any illegal instruction BSOD. So either that instruction was never used (hardly believable), or the chip /said/ it didn't support it, but actually did, or did a simple XCHG instead, or the OS felt back on legacy code from W95, which didn't need (and use?) that instruction.

    The box was not extremely instable either.

  26. A says:

    Unfortunately this article neglects to mention and explain two important timing features and how they are used and more importantly how they SHOULD be used in relation to/as compared to QPC:

    Multimedia Timers (TimeGetTime)

    Timer Queues/Synchronization (CreateTimerQueueTimer, etc.), which seem to be intended to obsolete Multimedia Timers (As seen here: msdn.microsoft.com/…/dd757634%28v=vs.85%29.aspx)

    And since those are not mentioned, we still have no explanation for behaviour like this: omeg.pl/…/on-winapi-timers-and-their-resolution

    Maybe you could ask the kernel folks if they might consider additionally addressing these as well in a future update of the article, or something like that? :)

    [Timer queues are not intended to replace multimedia timers. They are the opposite of multimedia timers! Timer queues have high latency because of, y'know, queueing. -Raymond]
  27. A says:

    Also, this article is missing a reference to KB938448 (support.microsoft.com/…/en), which it probably needs.

  28. Gabe says:

    Raymond: I think A was referring to the part of the MSDN docs for timeSetEvent that say "This function is obsolete. New applications should use CreateTimerQueueTimer".

    Perhaps it should say that it is obsolete for non-multimedia situations, because the current wording certainly implies that no new application should use it. And the timer queue docs say nothing about latency or what kind of applications may be inappropriate for use.

    [I'm not sure why that recommendation is there. CreateTimerQueueTimer is another way to create a periodic timer, but it is high latency due to queueing. -Raymond]

Comments are closed.