Jump to content
  • Advertisement
Sign in to follow this  
VanillaSnake21

How to properly get delta time on modern hardware?

This topic is 477 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

I'm just doing some optimization on my framework and would like to start multithreading it, however as of now the only way I found how to keep time that was somewhat reliable was winapi QPC functions for high rez timers, however I'm having to lock my cpu to a single core as a result. I've also just read an article saying that it's ill advised to used QPC for low rez things like game logic and instead use timeGetTime. I've rewritten my code as such but timeGetTime() - currentTime always seems to return zero. I think it's in a different thread and just executing my code in less than an ms. So I would like to know the definitive answer as to how to do this properly on multicores.

Share this post


Link to post
Share on other sites
Advertisement

> winapi QPC

 

Make sure to not mix nanoseconds/microseconds/etc. with milliseconds.

Also, there's no guarantee that each core will have the same value returned by QueryPerformanceCounter().

 

> I've rewritten my code as such but timeGetTime() - currentTime always seems to return zero.

 

Well, those two seems to be the same thing, the current time.

 

Also, did you make a multi-theaded main loop or are you creating a particular thread to execute just a brief code? If doing multi-thread, the usual is to make the main loop multi-threaded, and each thread has their own track of the time. Physics threads, for example, **usually** run with fixed delta time (16 milliseconds). It seems that you are doing the second, however, creating a thread in the middle of the main loop and mixing timers of both threads (?).

 

> So I would like to know the definitive answer as to how to do this properly on multicores.

 

There's on definitive answer. That pretty much depends how you are making your main loop (and how you are makin the thread, as I mentioned above).

Share this post


Link to post
Share on other sites

From what I remember using QPC unlocked the numbers were really random as the code jumped cores. So you're saying that it is the preferred method? And I can call from any core to get same exact timing now?

Share this post


Link to post
Share on other sites
Why are you locking to a single core for QueryPerformanceCounter? The whole reason you use QPC instead of RDTSC is so you don't have to lock it to a specific core. If there's a legit reason, you should probably just make a dumb thread for it and not much else since you don't want to rely on a specific core for your core game loop or something. Then just have a variable updated that the other threads read.

Unless Microsoft changed the specification for TimeGetTime, it is entirely inappropriate for a high-resolution time counter. It used to update only 64 times per second.

Share this post


Link to post
Share on other sites
 

 

> winapi QPC

 

Make sure to not mix nanoseconds/microseconds/etc. with milliseconds.

Also, there's no guarantee that each core will have the same value returned by QueryPerformanceCounter().

 

> I've rewritten my code as such but timeGetTime() - currentTime always seems to return zero.

 

Well, those two seems to be the same thing, the current time.

 

Also, did you make a multi-theaded main loop or are you creating a particular thread to execute just a brief code? If doing multi-thread, the usual is to make the main loop multi-threaded, and each thread has their own track of the time. Physics threads, for example, **usually** run with fixed delta time (16 milliseconds). It seems that you are doing the second, however, creating a thread in the middle of the main loop and mixing timers of both threads (?).

 

> So I would like to know the definitive answer as to how to do this properly on multicores.

 

There's on definitive answer. That pretty much depends how you are making your main loop (and how you are makin the thread, as I mentioned above).

 

Ok so you're saying not to use QPC, it seems there is no consensus. 

Of course I meant lastTime there.

I'm also not doing anything multithreaded yet, I mentioned that because as of now I only have 1 core masked and I would like to be able to let the app access all the cores.


Why are you locking to a single core for QueryPerformanceCounter? The whole reason you use QPC instead of RDTSC is so you don't have to lock it to a specific core. If there's a legit reason, you should probably just make a dumb thread for it and not much else since you don't want to rely on a specific core for your core game loop or something. Then just have a variable updated that the other threads read.

Unless Microsoft changed the specification for TimeGetTime, it is entirely inappropriate for a high-resolution time counter. It used to update only 64 times per second.

I was getting very weird results when last tried, it would spit out random numbers I guess as the cores switched under the code. Maybe as hodgeman said, they fixed it? I have to see. But I remember that I had to lock it to one thread back when I first wrote this code for it to work. I also don't really need high res time as of now, I'm simply using QPC for lack of options as nothing else works for me. 

Share this post


Link to post
Share on other sites

 

 

> winapi QPC

 

Make sure to not mix nanoseconds/microseconds/etc. with milliseconds.

Also, there's no guarantee that each core will have the same value returned by QueryPerformanceCounter().

 

> I've rewritten my code as such but timeGetTime() - currentTime always seems to return zero.

 

Well, those two seems to be the same thing, the current time.

 

Also, did you make a multi-theaded main loop or are you creating a particular thread to execute just a brief code? If doing multi-thread, the usual is to make the main loop multi-threaded, and each thread has their own track of the time. Physics threads, for example, **usually** run with fixed delta time (16 milliseconds). It seems that you are doing the second, however, creating a thread in the middle of the main loop and mixing timers of both threads (?).

 

> So I would like to know the definitive answer as to how to do this properly on multicores.

 

There's on definitive answer. That pretty much depends how you are making your main loop (and how you are makin the thread, as I mentioned above).

 

Ok so you're saying not to use QPC, it seems there is no consensus. 

Of course I meant lastTime there.

I'm also not doing anything multithreaded yet, I mentioned that because as of now I only have 1 core masked and I would like to be able to let the app access all the cores.

 

 

No, I mean you should use QPC, but it seems you are spawning a thread that has a brief life-time, I'm not sure (that's why I put that "?" there). While the usual approach is to create two (or more threads) that will start in the beginning of the program and end only when the application terminate.

Edit:

and possibly using a fixed time step for one of the threads.

Edited by felipefsdev

Share this post


Link to post
Share on other sites

Also, there's no guarantee that each core will have the same value returned by QueryPerformanceCounter().

This is just incorrect. If you are getting different values from different cores, it is a bug with the hardware timer being accessed (or more likely the BIOS code providing access to that hardware timer). If you do anticipate such bugs, I'd still use QPC or RDTSC locked to a core and publish that value for other threads.

Also, did you make a multi-theaded main loop or are you creating a particular thread to execute just a brief code? If doing multi-thread, the usual is to make the main loop multi-threaded, and each thread has their own track of the time. Physics threads, for example, **usually** run with fixed delta time (16 milliseconds). It seems that you are doing the second, however, creating a thread in the middle of the main loop and mixing timers of both threads (?).

They still would have the same problem since a single thread can and will change cores over time. And I advise against each thread having its own time. There is only disadvantages over publishing it from one thread (your highest resolution one) and having all others use that. You'd have sync issues since physics and animation and sound and everything else are all supposed to happen in a coordinated manner.

There's on definitive answer. That pretty much depends how you are making your main loop (and how you are makin the thread, as I mentioned above).

There is a definitive answer from Microsoft. If you're using Windows, they tell you the best practice is using QPC. While that doesn't mean you can't hit bugs, it does mean those bugs are more likely to get fixed since they are breaking the preferred solution.

(Edit) Minor clarification: I mention RDTSC, but only recommend it if you are locking on a specific core. And I don't particularly recommend doing that unless absolutely necessary (hint: it probably is not necessary!)

Share this post


Link to post
Share on other sites

> This is just incorrect. If you are getting different values from different cores, it is a bug with the hardware timer being accessed (or more likely the BIOS code providing access to that hardware timer). If you do anticipate such bugs, I'd still use QPC or RDTSC locked to a core and publish that value for other threads.

 

Huh, that's exactly the reason there's no guarantee they won't return the same value.

 

> They still would have the same problem since a single thread can and will change cores over time. And I advise against each thread having its own time. There is only disadvantages over publishing it from one thread (your highest resolution one) and having all others use that. You'd have sync issues since physics and animation and sound and everything else are all supposed to happen in a coordinated manner.

 

Using a different timer (like using a fixed time step for physics engine) is very common among engines (Unity, Godot, Unreal, for example).

 

> There is a definitive answer from Microsoft. If you're using Windows, they tell you the best practice is using QPC. While that doesn't mean you can't hit bugs, it does mean those bugs are more likely to get fixed since they are breaking the preferred solution.

 

I wasn't talking about using QPC or not using QPC, I was talking about how he's calculating the timer. And that synchronization will depend on how he's spawning the threads.

Edited by felipefsdev

Share this post


Link to post
Share on other sites

 

 

 

> winapi QPC

 

Make sure to not mix nanoseconds/microseconds/etc. with milliseconds.

Also, there's no guarantee that each core will have the same value returned by QueryPerformanceCounter().

 

> I've rewritten my code as such but timeGetTime() - currentTime always seems to return zero.

 

Well, those two seems to be the same thing, the current time.

 

Also, did you make a multi-theaded main loop or are you creating a particular thread to execute just a brief code? If doing multi-thread, the usual is to make the main loop multi-threaded, and each thread has their own track of the time. Physics threads, for example, **usually** run with fixed delta time (16 milliseconds). It seems that you are doing the second, however, creating a thread in the middle of the main loop and mixing timers of both threads (?).

 

> So I would like to know the definitive answer as to how to do this properly on multicores.

 

There's on definitive answer. That pretty much depends how you are making your main loop (and how you are makin the thread, as I mentioned above).

 

Ok so you're saying not to use QPC, it seems there is no consensus. 

Of course I meant lastTime there.

I'm also not doing anything multithreaded yet, I mentioned that because as of now I only have 1 core masked and I would like to be able to let the app access all the cores.

 

 

No, I mean you should use QPC, but it seems you are spawning a thread that has a brief life-time, I'm not sure (that's why I put that "?" there). While the usual approach is to create two (or more threads) that will start in the beginning of the program and end only when the application terminate.

Edit:

and possibly using a fixed time step for one of the threads.

 

No that can't be because I'm working in completely single threaded code, so I can't be spawning anything. I assumed you said that QPC can provide variable times from core to core so no don't use it?


 

Also, there's no guarantee that each core will have the same value returned by QueryPerformanceCounter().


This is just incorrect. If you are getting different values from different cores, it is a bug with the hardware timer being accessed (or more likely the BIOS code providing access to that hardware timer). If you do anticipate such bugs, I'd still use QPC or RDTSC locked to a core and publish that value for other threads.
 

Also, did you make a multi-theaded main loop or are you creating a particular thread to execute just a brief code? If doing multi-thread, the usual is to make the main loop multi-threaded, and each thread has their own track of the time. Physics threads, for example, **usually** run with fixed delta time (16 milliseconds). It seems that you are doing the second, however, creating a thread in the middle of the main loop and mixing timers of both threads (?).


They still would have the same problem since a single thread can and will change cores over time. And I advise against each thread having its own time. There is only disadvantages over publishing it from one thread (your highest resolution one) and having all others use that. You'd have sync issues since physics and animation and sound and everything else are all supposed to happen in a coordinated manner.
 

There's on definitive answer. That pretty much depends how you are making your main loop (and how you are makin the thread, as I mentioned above).


There is a definitive answer from Microsoft. If you're using Windows, they tell you the best practice is using QPC. While that doesn't mean you can't hit bugs, it does mean those bugs are more likely to get fixed since they are breaking the preferred solution.

 

But Windows has been pushing for QPC for commercial reasons not because it's the proper way. So i'm a little skeptical when reading into it. 

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!