Solved

High res time - QueryPerformanceCounter

Posted on 1997-09-10
13
322 Views
Last Modified: 2013-12-03
I'm wondering why I can't get QueryPerformanceFrequency/QueryPerformanceCounter to work. I need microsend level timing info but these API's return TRUE/0, indicating that they're not available.  I'm working on a Pentium notebook
0
Comment
Question by:mgrinnell
  • 5
  • 5
  • 3
13 Comments
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
Try using the multimedia timers instead - eg. timeGetTime()

0
 

Author Comment

by:mgrinnell
Comment Utility
I appreciate your suggestion, but as I mentioned I need a timer with a resolution of a microsecond or so -- timeGetTime() is only good to the millisecond.  The documentation suggests that the availability of QueryPerformanceCounter() is a hardware issue, but my understanding was that on a Pentium system it just queried timing info from the chip.  I'd like to know if there's anything I can do to make that API work on my machine, or if there's another way to get timer info with the accuracy I need.
0
 
LVL 4

Expert Comment

by:davmarc
Comment Utility
You're in the right direction - QueryPerfomance*() is the most accurate way to time code.

Did you try your code on a desktop Pentium?
They should work...maybe the problem is involved in the particular organization of notebooks (hmmm...).

Davide Matcato.
0
 

Author Comment

by:mgrinnell
Comment Utility
I sent it to a friend on a desktop Pentium and he got the same result; QueryPerformanceFrequency() returns TRUE.  The Performance Monitoring section of the help file talks a lot about registry manipulation, but I think this is just to monitor system functions, not to enable the QueryPerformance* API's.  I'm still looking...
0
 
LVL 4

Expert Comment

by:davmarc
Comment Utility
mgrinnel,
FALSE = 0 = counter not available
TRUE = non-0 = counter available

If it returns TRUE (which is *not* zero as you mentioned in the original question), that means the counter is supported!

Davide Marcato.
0
 

Author Comment

by:mgrinnell
Comment Utility
Davide,

Sorry I wasn't clear.  QueryPerformanceFrequency() returns TRUE and QueryPerformanceCounter() returns 0.  For QueryPerformanceFrequency(), a return value of TRUE means that the API is not supported on your machine.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 4

Accepted Solution

by:
davmarc earned 100 total points
Comment Utility
>For QueryPerformanceFrequency(), a return value of TRUE means
>that the API is not supported on your machine.

This is simply not correct. Both QPFrequency() e QPCounter() return TRUE if the hardware counter *is* supported.
Hence they are very unlikely to return different values...

Try the following code:

#include <windows.h>

void main()
{
      LARGE_INTEGER value;
      BOOL result;
      result = QueryPerformanceFrequency(&value);
      result = QueryPerformanceCounter(&value);
}

Running it under a debugger, what are the values returned by the two APIs? On my computer I see "1" and "1".

Davide Marcato.
0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
Why is this a point of contention - check out the documentation it is clearly stated:

==========
QueryPerformanceFrequency

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists.

BOOL QueryPerformanceFrequency(
LARGE_INTEGER *lpFrequency // address of current frequency);

Parameters
lpFrequency
Points to a variable that the function sets, in counts per second, to the current performance-counter frequency. If the installed hardware does not support a high-resolution performance counter, this parameter can be to zero.

Return Values
If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the installed hardware does not support a high-resolution performance counter, the return value is zero.
==========

SO a value of TRUE (non-zero) means "the installed hardware supports a high-resolution performance counter".  A value of FALSE (0) means "the installed hardware does not support a high-resolution performance counter".

It is that simple.

For QueryPerformanceCounter the dos says:

==========
QueryPerformanceCounter

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter, if one exists.

BOOL QueryPerformanceCounter(
LARGE_INTEGER *lpPerformanceCount // address of current counter value);

Parameters
lpPerformanceCount
Points to a variable that the function sets, in counts, to the current performance-counter value. If the installed hardware does not support a high-resolution performance counter, this parameter can be to zero.

Return Values
If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the installed hardware does not support a high-resolution performance counter, the return value is zero.
==========

Here (also) non-zero (TRUE) means it is supported and zero (FALSE) means it is not.


If both calls are TRUE, all is well, if both are FALSE then not supported.  However, if one is TRUE and the other FALSE - then we have a more interesting situation.

Are you passing a valid LARGE_INTEGER to the calls?

BTW: QueryPerofrmanceXXX routines don't guarantee microsecond timing - it depends on your PC.

0
 
LVL 4

Expert Comment

by:davmarc
Comment Utility
Ronslow, apart from also reporting the documentation, you said exactly the same as me! :-)
TRUE = supported, FALSE = not supported.

Davide Marcato.
0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
My point is - why was there a question about return values in the  first place?

Also thought I'd lend a bit of officiality by quoting the documentation (just so there could be no doubt about it).

I'm still confused, however, about what return values mgrinnell is actually getting.  Can one call return true and the other false.  
Does GetLastError provide any extra information on the possible reason if this is so?

0
 

Author Comment

by:mgrinnell
Comment Utility
Yikes.  My documentation, which I'll quote here so you don't think I'm insane, says:
---------
The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists.

BOOL QueryPerformanceFrequency(

    LARGE_INTEGER  *lpliPerformanceFreq       // address of current frequency
   );      
Parameters

lpliPerformanceFreq

Points to a variable that the function sets, in counts per second, to the current performance-counter frequency. If the installed hardware does not support a high-resolution performance counter, this parameter can be to zero.

Return Value

If the installed hardware supports a high-resolution performance counter, the return value is FALSE; otherwise, it is TRUE. To get extended error information, call GetLastError.
---------
So here, QPF() returning TRUE is consistent with QPC() returning 0. I think GetLastError was returning 127 - PROC_NOT_FOUND.  I'm working with an older version of our product that compiles with an older version of msvc, though.  I'll check it out with the latest and greatest next week and report back.

Thanks again for your help!
Mark
0
 
LVL 4

Expert Comment

by:davmarc
Comment Utility
What version of VC++ you are reading the documentation of?
I refer to VC++ 5.0.

Davide Marcato.
0
 

Author Comment

by:mgrinnell
Comment Utility
(Sorry for the delay - I've been in Germany for a few weeks.) You're exactly right, the API works fine on my machine -- my only problem was paying attention to the old, incorrect documentation. It's funny, I was converting this from an OS/2 version that didn't do any error checking - If I hadn't added the check along the way, I would have been fine.  I guess that'll teach me.

0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now