QueryPerformanceFrequency - Negative value

This is a discussion on QueryPerformanceFrequency - Negative value within the C++ Programming forums, part of the General Programming Boards category; For some reason I get a negative value from this function on some computers. I really can not switch to ...

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    49

    QueryPerformanceFrequency - Negative value

    For some reason I get a negative value from this function on some computers.
    I really can not switch to another function such as GetTickCount because I have a big application which uses QueryPerformanceFrequency all over.

    I already tried to do
    QueryPerformanceFrequency(&ticksPerSecond); //freq in [counts per second]
    unsigned __int64 Ufreq = ticksPerSecond.QuadPart;

    It doesn't help...

    Any suggestions?

    I can't seem to find a solution on the web even though this problem occurs on more than one computer...And this function is quite an important one I assume...

    Thank you

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    You're assigning to an unsigned integer. The value cannot be negative.

    It could be large enough that it is interpreted as negative when used through a signed output function, of course. Which is a program error in itself, but not your actual problem, because I can't think of a computer with sub-microsecond timer resolution.

    A better guess is that QueryPerformanceFrequency() fails (test the return value!) and you simply read uninitialized memory. If QPF returns FALSE, you need to call GetLastError() to find out what went wrong. In particular, if the computer has no sound, the function might fail, as performance counters are often implemented in sound hardware.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    More code?

    MSDN says it takes a pointer to LARGE_INTEGER which has LowPart and HighPart but no QuadPart.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,014
    Actually, according to MSDN:
    Code:
    typedef union _LARGE_INTEGER
    {
    	struct
    	{
    		DWORD LowPart;
    		LONG HighPart;
    	};
    	struct
    	{
    		DWORD LowPart;
    		LONG HighPart;
    	} u;
    	LONGLONG QuadPart;
    } LARGE_INTEGER,  *PLARGE_INTEGER;
    Last edited by Elysia; 12-30-2007 at 04:45 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    I don't believe there is any such animal as unsigned __int64 Ufreq

    A simple example follows:

    Code:
    #include <windows.h>
    #include <stdio.h>
    
    LARGE_INTEGER curTime; 
    LARGE_INTEGER lastTime; 
    LARGE_INTEGER startTime; 
    LARGE_INTEGER frequency; 
    
    void initialize(void) 
    { 
        QueryPerformanceFrequency(&frequency); 
        QueryPerformanceCounter(&lastTime); 
        startTime.QuadPart = 0; 
    } 
    
    void start(void) 
    { 
        QueryPerformanceCounter(&startTime); 
    } 
    
    double getTime(void) 
    { 
        QueryPerformanceCounter(&curTime); 
        return (double)((curTime.QuadPart-startTime.QuadPart)/(double)frequency.QuadPart); 
    } 
    
    int main(void)
    {
        initialize(); 
        UINT64 Ufreq = frequency.QuadPart;    
        printf("Frequency is %I64u\n", Ufreq);
        start();
        Sleep(2000);
        printf("Elapsed time %f\n", getTime());
        return 0;
    }
    Last edited by BobS0327; 12-30-2007 at 05:04 PM. Reason: Changes to accurately reflect UINT64

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,834
    The first question would be HOW are you printing it?
    Messing up the detail of the printf format string is one common way.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  7. #7
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    I don't believe there is any such animal as unsigned __int64 Ufreq
    I stand corrected. The above statement is incorrect. There is a UINT64 which is typedef'd as unsigned __int64. As Salem says, it's probably how you're printf'ing it.

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    49

    Lightbulb Solved

    SOLVED

    the solution, in case someone else needs it (and I can't see a reason why not...It's a very useful and problematic function)

    Code:
    LARGE_INTEGER ticksPerSecond;
    LARGE_INTEGER tick1;   // A point in time
    LARGE_INTEGER tick2;   // Another point in time
    UINT64 Utick1, Utick2, Ufreq;
    
    // get the high resolution counter's accuracy
    QueryPerformanceFrequency(&ticksPerSecond);	//freq in [counts per second]
    Ufreq = ticksPerSecond.QuadPart;
    
    MessageBox(NULL,"In Thread, lets sleep for 0.001[sec] and see how long it really took", NULL, NULL);
    
    QueryPerformanceCounter(&tick1);	//get current clock count
    Sleep(1);
    QueryPerformanceCounter(&tick2);	//get current clock count
    Utick1=tick1.QuadPart; //THIS IS THE IMPORTANT THING. CONVERT TO UNSIGNED
    Utick2=tick2.QuadPart;					
    UINT64 deltaCounts = (Utick2-Utick1);
    double deltaTime = (double)deltaCounts / (double)Ufreq;
    					
    strstream os; //BETTER TO USE STRSTREAM AND NOT SPRINTF
    os << "freq "<<Ufreq<<endl
            <<"delta counts "<<deltaCounts<<endl
    	<<"delta time " << deltaTime << endl;
    
    MessageBox(NULL, os.str(), NULL, NULL);
    Thank you all very much for helping!!!

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,014
    And just for curiosity's sake, what result did you get?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    49
    Quote Originally Posted by Elysia View Post
    And just for curiosity's sake, what result did you get?
    Using function QueryPerformanceFrequeny()

    On the "problematic" computer, which is just another computer I need to use now (Pentium 3GHz D)
    freq = 3000150000 // [counts/sec]

    And on the computer I wrote the whole code (Pentium 2.66GHz)
    freq = 3579545

    How the HELL there is such a HUGE difference?!
    Last edited by misterowakka; 01-01-2008 at 10:20 AM.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,834
    Mmm, both those functions return a result, which you don't check.

    Perhaps they're failing, and you're computing garbage.

    Also, read some advisory comments. For example, are you running on a dual-core machine, and the OS schedules your program from one processor to the other whilst in the Sleep().
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  12. #12
    Registered User
    Join Date
    Dec 2007
    Posts
    49
    Quote Originally Posted by Salem View Post
    Mmm, both those functions return a result, which you don't check.

    Perhaps they're failing, and you're computing garbage.

    Also, read some advisory comments. For example, are you running on a dual-core machine, and the OS schedules your program from one processor to the other whilst in the Sleep().
    1) Thanks a lot
    2) I did try to check the returned value

    Code:
    if(QueryPerformanceFrequency(&ticksPerSecond)==FALSE)	//freq in [counts per second]
    	MessageBox(hWnd, "freq problem", NULL, NULL);
    It doesn't fail and I get a constant value. Doesn't it mean that the function is fine? If it used different processors I would have got changing values, wouldn't I?

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,834
    I dunno, but from what I've read in the past, it's not entirely an easy ride working with the performance counters.

    For example, I don't know where QueryPerformanceFrequency() gets it's information. Is there some register on the processor, or is it some computed value effectively stored in the registry somewhere.

    As already mentioned in the various links, the QueryPerformanceCounter() value is NOT synchronised between multiple cores.

    I also doubt that QueryPerformanceFrequency() takes into account the effects of say power management (or temperature management) changing the processor frequency from one moment to the next. Even if it is accurate at the point of the call, a 1mS sleep is ample enough time for something to decide the machine is less busy and throttle back the CPU clock frequency in time for the next QueryPerformanceCounter() call.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,014
    I'd say it's pretty likely you'd get a negative value. Consider this:
    Code:
    	UINT64 nFreq;
    	LARGE_INTEGER n;
    	ASSERT( QueryPerformanceFrequency(&n) );
    	nFreq = n.QuadPart; // The frequency is the number of ticks it counts per second
    
    	INT64 nInt64Max = 0xFFFFFFFFFFFFFFFF / 2; // 0xFFFF FFFF FFFF FFFF
    	UINT64 nProcessorFreq = UINT64(2.5 * 1000000000); // 10 ^ 9 Number of cycles per second the processor does
    	UINT64 nCyclesInSecs = nInt64Max / (nProcessorFreq * nFreq); // Divide the number of cycles with the number of ticks per second
    	UINT64 nCyclesInMins = nCyclesInSecs / 60;
    	UINT64 nCyclesInHours = nCyclesInMins / 60;
    	UINT64 nCyclesInDays = nCyclesInHours / 24;
    And the result?

    nFreq = 3 579 545
    nInt64Max = 9 223 372 036 854 775 807
    nProcessorFreq = 2 500 000 000
    nCyclesInSecs = 1030
    nCyclesInMins = 17
    nCyclesInHours = 0
    nCyclesInDays = 0
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Convert bytes to int, keep the negative number
    By umm in forum C Programming
    Replies: 7
    Last Post: 03-20-2009, 05:47 PM
  2. Keep getting negative sign after answer
    By uptown11 in forum C++ Programming
    Replies: 7
    Last Post: 02-23-2009, 11:14 PM
  3. Can we input negative numbers in the output windiw
    By hitesh1511 in forum C Programming
    Replies: 1
    Last Post: 08-22-2006, 01:07 AM
  4. Negative Numbers
    By Quantrizi in forum C++ Programming
    Replies: 7
    Last Post: 10-12-2003, 01:48 AM
  5. how to handle integer overflow in C
    By kate1234 in forum C Programming
    Replies: 8
    Last Post: 04-23-2003, 01:20 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21