Skip to main content
gamedev.net
🔒 Locked

Problems with GetPerformanceFrequency

Started by Koen VB Dec 29, 2002 at 5:05 PM 8 replies 1k views
Original Post
Koen VB
Koen VB
Hi, I use GetPerformanceFrequency and GetPerformanceCount for timing animation. The problem is that the frequency I obtain seems way to low. The frequency is only 3579545 counts, while the average time between frames is 22834309 counts! If the numbers are correct, this would equal an interval of 6.38 seconds! This is what I get when I do a quickwatch in VC++: Frequency.LowPart 3579545 Frequency.HighPart 0 Frequency.QuadPart 3579545 What am I doing wrong? --------- http://users.pandora.be/koen.van.baelen ---------
billybob
billybob
only?

3579545, thats 3.5 million ticks per second. if you are running at 60 fps, thats at least 50,000 ticks per frame. if thats not enough, nothing is. here is how i use it (but wrapped in a class)



LARGEINTEGER Frq;
LARGEINTEGER Stop;
LARGEINTEGER Start;
int delta; //how much everything should be moved

QueryPerformanceFrequency(&Frq);

//more code

Stop.QuadPart = 0; //so the first frame isn''t messed up
Start.QuadPart = 0;
while(true) //game loop
{
delta = int((Stop.QuadPart - Start.QuadPart) / Frq.QuadPart); //get rid of compiler warning.
QueryPerformanceCounter(&Start);
//game loop code
QueryPerformanceCounter(&Stop);
}

if delta somehow exceeds integer capacity, the frame is worthless anyway. in my engine, if delta is greater than 3 seconds, i set it to 0 and wait until it calms down before continuing the loop. if its greater than 3 seconds, your program was probably minimized, so delta shouldn''t be goign anyway.
Dean Harding
Dean Harding
What''s your code look like? I assume it''s something like this:

LARGE_INTEGER freq;
::QueryPerformanceFrequency( &freq );


Cause for me that give a little over 1.5 billion... which is interesting, cause it seems to be the frequency of my CPU clock...

If I had my way, I''d have all of you shot!


codeka.com - Just click it.

billybob
billybob
well, thats why theres a queryperformancefrequency, so you can divide your timer results by it to get the same timing on all computers. on the old computer in the other room, i get like 700,000 as the frequency, pitiful

Dean Harding
Dean Harding
quote:
Original post by billybob
well, thats why theres a queryperformancefrequency, so you can divide your timer results by it to get the same timing on all computers. on the old computer in the other room, i get like 700,000 as the frequency, pitiful




Yes, but if you look at the OP, he''s getting what equates to about 6 seconds between frames (which I assume is wrong). 3M counts per second and 22M counts between frames.

Perhaps, Koen VB, you can post both the code you use to get the frequency, and the code you use to get the time difference?

If I had my way, I''d have all of you shot!


codeka.com - Just click it.

Koen VB
Koen VB
This is my code:

bool TGameApp::InitTimer(void)
{
if (QueryPerformanceFrequency(&Frequency))
{
QueryPerformanceCounter(&Count);
return true;
}
else return false;
}

float TGameApp::GetInterval(void)
{
LARGE_INTEGER Time;
float Interval;

QueryPerformanceCounter(&Time);
Interval = (Time.QuadPart - Count.QuadPart) / Frequency.QuadPart;
Count.QuadPart = Time.QuadPart;
return Interval;
}

---------
http://users.pandora.be/koen.van.baelen
---------
Koen VB
Koen VB
Hi,
I was thinking, is it possible that the value is too high for a LARGE_INTEGER type? If the frequency would equal the cpu speed, that could explain it.

---------
http://users.pandora.be/koen.van.baelen
---------
dalleboy
dalleboy
Try this instead:

    
float Interval = (float) (Time.QuadPart - Count.QuadPart) / (float) Frequency.QuadPart;


The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter. You cannot count on that it is the same as the CPU frequency.

quote:
Original post by Koen VB
This is what I get when I do a quickwatch in VC++

You cannot expect QueryPerformanceCounter to work if you are pausing the program in the debugger. The high-resolution performance counter will continue to count even if you have paused your program, and thus you will get the 'wrong' result when you unpause your program again.

EDIT 1: Added some more comments.



Update GameDev.net system time campaign: 'date ddmmHHMMYYYY'

[edited by - dalleboy on January 2, 2003 1:56:39 PM]
billybob
billybob
i think its easier to write a timer class, i have mine like this:

class CTimer
{
//timer vars here, mine has these 5:
LARGE_INTEGER m_CumulativeTime;
LARGE_INTEGER m_Frequency;
LARGE_INTEGER m_StopTime;
LARGE_INTEGER m_StartTime;
bool m_Stopped;
public:
CTimer(); //calls queryperofmrancefrequency to calibrate
~CTimer(); //empty

//then have 4 functions:
Reset(bool StartTimer); //reset the timer to 0, if startimer is true, it starts the timer.
Stop(); //this will stop the timer, and keep the result
Start();
GetTime(); //this will return the total time its been running, as in the total time between start-stop functions, and best of all its calibrated to Frequency so you don''t have to worry about that in the loops. i have mine set to return fractions of milliseconds, so i can time things based off of ''real'' time in my engine, as in seconds, minutes, etc
};

that way, you can make multiple times really easily, and its simple to get delta (time elapsed since last frame)


CTimer DeltaTimer;

//beginning of main loop
{
float delta = DeltaTimer.GetTime();
DeltaTimer.Reset(true);
//blah blha
}


then just multiply all movement by delta.

this way, if for some reason you want a timer for something else, its super easy to implement.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.