Jump to content
  • Advertisement
Sign in to follow this  
Gruik

High resolution counter

This topic is 4894 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, In my multiplayer game, i may need that things move at the same speed on each client. So, i'd like to use a seperate thread for moving my objects and displaying. Moving and displaying in the same thread may force my objects to move at the monitor frequency, because directx' Device::Present() waits for vertical retrace before copying backbuffer. Moving things in my game will have a speed expressed in "unit of measure per unit of time" where unit of measure is defined and unit of time may be µs or ms. I'm using C# and hoped to use Environment.TickCount that should return the number of elapsed milliseconds since the beginning of the program. But i've made some tests and its accuracy seem to be computer specific. On my computer, it provides a new value only each 16ms (62,5Hz, quite my monitor frequency). It's the same for TimeDate.Now.Ticks. I've found this win32 function that i could import in my c# code : QueryPerformanceCounter() But i've read this is not available on every systems. Do you know on which kind of systems this is unavailable? or do you know another method to fetch a better counter?

Share this post


Link to post
Share on other sites
Advertisement
Here's some information on timers. From that page:
Quote:

The Pentium processor and most PC compatible processors such as AMD support a high-resolution Performance Counter, which can provide a resolution of less than one microsecond.

The QueryPerformanceFrequency function is used to determine the actual frequency of the counter. This is the numeric value that the Performance Counter will increase by in 1 second.

The QueryPerformanceCounter function is used to read the Performance Counter, which may be divided by the counter frequency to determine the time in seconds.

Both of these functions take a pointer to a LARGE_INTEGER union, which will be filled with the requested value if the function is successful.

The function will return 0 on failure, or non-zero on success.


Ideally what you should do is something like this. Have support for two timers in case the QueryPerformanceCounter does not exist. Other than that, that timer is the best you can have. I don't know how much of help that code is begin in C++ format, but hopefully you can get the idea of what to do. Good luck! [smile]

Share this post


Link to post
Share on other sites
Oh, i see
You use another counter method if QueryPerformanceCounter is not available

Thanks

Share this post


Link to post
Share on other sites
timeGetTime with a call to timeBeginPeriod(1) in the beginning and timeEndPeriod(1) in the end isn't as accurate as QueryPerformanceCounter which uses the TSC, but is more accurate than the ones you describe, so it could be a good second choice for a timer.

You should be aware of mobile processors that can change their clock frequency, because then your timing won't work if you're using the ones that totally rely on the frequency, like QueryPerformanceCounter. timeGetTime will do the job in those cases, so that should be a good second choice for a timing system.

Share this post


Link to post
Share on other sites
i decided to learn and test timeGetTime throughoutly before turning to QuerryPerformacneCounter but after running some tests on differen machines I noticed the in a longer loop the times vary. i don't really understand why but on one pc it takes the loop 10 sec to execute while on other machines it takes 7 or 15 seconds. the time factor is set to 0.01 second as with lower values differences between times to execute the loop vary much more.

can anyone explain to me this weir behaviour?

reagrds

Share this post


Link to post
Share on other sites
Quote:
Original post by ursus
i decided to learn and test timeGetTime throughoutly before turning to QuerryPerformacneCounter but after running some tests on differen machines I noticed the in a longer loop the times vary. i don't really understand why but on one pc it takes the loop 10 sec to execute while on other machines it takes 7 or 15 seconds. the time factor is set to 0.01 second as with lower values differences between times to execute the loop vary much more.

can anyone explain to me this weir behaviour?

reagrds


If the OS is multithreaded anything could happen in between your loop start and end. If you haven't, you should set the priority of your thread to real-time to get the best/most accurate results. I'm assuming that you did shut down all other programs that could be shut down without trouble (anti-virus, firewall, messenger etc.) while you were testing it?

I haven't tested timeGetTime on my computers yet, but I would certainly make sure that my above terms are reached before testing - otherwise it could just as easily be another program(s) that were causing the slowdown.

Share this post


Link to post
Share on other sites
most likely you're right, but if so, can someone explain to me how it's done with pro games? even those short and simple ones appear to run at constant speed (despite changing frame rates) on most pcs?

Share this post


Link to post
Share on other sites
Two things: Don't use QueryPerformance*, because it doesn't work properly on computers that vary their cpu speed. Almost all laptops do this, and most modern pentium 4 processors do as well (and in the future, AMDs will likely do the same).

Next, leave your game's process priority set to normal. To do otherwise will interfere with the operating system in a negative way, and can cause the whole system to become so unresponsibe that the only option for the user is to do a manual reboot (on modern machines that means either holding the power button for a while or pulling the plug).

Finally, it shouldn't matter how long the frame takes as long as you base movement on time. If you're doing straight line movement, then each frame you just do position += velocity * time. For more complicated systems (with things like gravity, acceleration and that kind of thing), you need more advanced systems (called numerical integrators). A popular and rather accurate one is calld RK4

Share this post


Link to post
Share on other sites
Extrarius,

i caould put some example source here, but i'll just resort to famous NEHE 21 tutorial. when i ran it on different pcs it works with differen speed. so it's the question of the code i suppose.

i heard about accumulators. have you got any experience using them? are they worth learning and implementing?

take care

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!