Jump to content
  • Advertisement
Sign in to follow this  

This topic is 4413 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone. I apologize in advance if this question gets asked or topic brought up too frequently, I did my best to search through the forums but I did not really arrive at material or a conclusion I was satisfied with. I am currently working on a very plain and basic engine in order to exercise and revitalize my programming skills which took a hiatus after leaving school and working 60-70 hrs a week for a few years :( I think I have done fairly well trying to pick up where I left off, I left highschool having a side scrolling shooter game with animated sprites and a few visual effects and framerate independant movement, a menu and a save/load system. Since I'm out of practice I decided to create a 2D tile based game so I could focus on regaining familiarity while learning a few new things from managed DX9 What I have now is a system that creates a device, loads textures and some tiles, I have a character that moves around these tiles with smooth scrolling, I can dynamically alter the size of the world, etc. and have a very rudimentary picking system going (I sort of branched off creating a 'level editor' of sorts so I can paint tiles and create a simple world). Up to this point my movement system had been by using QueryPerformance(Counter/Frequency) and I was just doing your basic Start, Process, End, End-Start/Freqency to gain a delta value to multiply my movements by. I have a dual-core system now, and I experiened the situation of having bogus values returned by QPC without the AMD processor driver installed. This prompted me to explore the situation, and sadly I haven't really come across much in terms of a resolution. I know that the AMD processor driver fixes the issue. I know why it's happening (registers from different CPUs, CPU frequency being scaled by power management although I have that disabled) and various other BIOS/HAL problems. My question I guess is: Is dealing with this just "how it's done"? I've seen solutions involving setting thread affinity, which I did to get it working without the AMD processor driver, but I guess the difficulty I am having is that everywhere I look everyone has a different reason why something should or shouldn't be used. People using getTickCount and whatnot get told by others to use QPC, other people using QPC get told by peopele that QPC isn't reliable, but everyone who is saying "don't use [x] method" generally doesn't have a method of their own to reccomend, and instead explains the solution in pseudocode. At the risk of asking a very silly question, I guess I want to know is what are the 'pros' using? For commercial games, how are they measuring time? I realize that it's going to be a lot more complicated, physics intensive games probably even factor in things like how long the query calls take in order to maximize precision, I'm not interested in developing an equivalent timer to what a commercial game would use, because I realize that is over my head right now, what I'm concerned or curious about is just knowing what direction I should work in so that I don't become familiar or overly dependant on a particular mechanism which ultimately turns out to work against me in the end. Also the whole DLLImport thing just doesn't 'feel' right working in a managed environment, is this simply the only way to do it?

Share this post


Link to post
Share on other sites
Advertisement
I don't think this is a silly question and I would also very much like to know the answer. I have just spent weeks learning how to use QueryPerformanceCounter etc to create framerate-independant movement and I am a bit concerned that all my code is going to break when multi-core processors become more prevalent.

Share this post


Link to post
Share on other sites
I'm pretty sure QPC is the best you can get. I've never had trouble with it, although you scare me a bit because I have a x2 dual-core on the way. You scare me in a good way though, because I'd rather it break on my system than the end-users.

Physics intensive games don't worry about exact timing, they worry about exact physics. If you want to get exact physics, you use time integral methods to determine the exact time of each collision, then update the objects accordingly.

At the start of each frame, you calculate the time since the last update using QPC. Its only called once per frame, so you don't need to worry about any overhead. Also, you want to make sure and update every object with the same timestep, so its a win-win situation.

GetTickCount does work in most cases. The only reason not to use it is accuracy. I have a networking program that measure ping using GetTickCount. The problem is my pings are either 0, 10, 20... and nothing in between.

So, in short, just use QPC (especially if you already got it working on your dual-core). And don't worry about the speed as it should only be called once per frame.

Share this post


Link to post
Share on other sites
I've heard that QueryPerformanceCounter returns erroneous information on multi-processor or multi-core processor systems, presumabley because each processor has its own performance counter.

Share this post


Link to post
Share on other sites
Thanks for the replys.

Quote:
You scare me in a good way though, because I'd rather it break on my system than the end-users.


I feel the same way. The break didn't occur until I switched from softwarevertexprocessing to hardware, strangely.. Not sure how that would have anything to do with QPC.

Here's my loop for the sake of it:


while (app.Created)
{
QueryPerformanceFrequency(ref freq);
QueryPerformanceCounter(ref start);
app.Update();
app.Render();
Application.DoEvents();
QueryPerformanceCounter(ref end);
app.fr = (float)((double)(end - start) / freq);
app.accumulator += app.fr;
}



Update checks to see if the accumulator has gone past a timeslice (1/60 in my case) and if it has, processes all necessary updates and decriments the accumulator by the framerate, etc. etc.

Anything I should change? I wasn't sure if I should continually call QPF to check for CPUs that throttle or not.

Share this post


Link to post
Share on other sites
Quote:
Original post by DaveInsurgent
*** Source Snippet Removed ***

To me you seem to have both a bit strange structure and a bit strange invoktion of QPC, check out PInvoke.net for the prefered way.

I would write that loop like this:

long fequency;
QueryPerformanceFrequency(out freqeuncy);
float freq = (float)frequency;

long oldTime;
long newTime;
float dt;
while (app.Created)
{
// Calculate the delta time.
oldTime = newTime;
QueryPerformanceCounter(out newTime);
dt = (newTime - oldTime) / freq;

// Now do delta time dependant stuff
app.Update(dt); // Pass the delta time
app.Render();

// I think this looks a bit dirty, but I'll just leave it here :)
app.accumulator += app.fr;

Application.DoEvents();
}







[Edited by - Enselic on April 21, 2006 7:37:20 AM]

Share this post


Link to post
Share on other sites
First, frequency scaling (Like AMD's Cool & Quiet) should *not* cause problems with QPC. At least according to Microsoft, that is "guaranteed" to work.

Multi-core systems are trickier though. There's an article about how to manage it somewhere on MSDN... Don't have the link though.
But as I remember, they basically suggest comparing the value returned from QPC to the last result, to see if it's reasonably close to the last result. If it starts telling you that -3 seconds has elapsed since last frame, you know there's something wrong... [wink]

But I guess a good start would be to just decide what kind of precision you need. timeGetTime can do 1ms precision, and works no matter what.

QPC is more accurate, but you start getting problems with multicore systems.
So, is 1ms enough? Then you don't even have to deal with this problem.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!