Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

High res time - QueryPerformanceCounter

Posted on 1997-09-10
13
Medium Priority
?
344 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

 

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 400 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

 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

Question has a verified solution.

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

If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
zlib is a free compression library (a DLL) on which the popular gzip utility is built.  In this article, we'll see how to use the zlib functions to compress and decompress data in memory; that is, without needing to use a temporary file.  We'll be c…
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…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

704 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