Solved

High res time - QueryPerformanceCounter

Posted on 1997-09-10
13
337 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
ID: 1406412
Try using the multimedia timers instead - eg. timeGetTime()

0
 

Author Comment

by:mgrinnell
ID: 1406413
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
ID: 1406414
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
MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

 

Author Comment

by:mgrinnell
ID: 1406415
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
ID: 1406416
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
ID: 1406417
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
 
LVL 4

Accepted Solution

by:
davmarc earned 100 total points
ID: 1406418
>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
ID: 1406419
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
ID: 1406420
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
ID: 1406421
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
ID: 1406422
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
ID: 1406423
What version of VC++ you are reading the documentation of?
I refer to VC++ 5.0.

Davide Marcato.
0
 

Author Comment

by:mgrinnell
ID: 1406424
(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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Visual Fox Pro commands 15 52
Excel Use VBA to get user's Mac Address for their computer 5 322
Need to create an object factory 2 49
Messagebox for a Web Site Application 4 81
This tutorial is about how to put some of your C++ program's functionality into a standard DLL, and how to make working with the EXE and the DLL simple and seamless.   We'll be using Microsoft Visual Studio 2008 and we will cut out the noise; that i…
This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
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…

680 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