Main loop timing

Started by
14 comments, last by Aliii 10 years, 5 months ago

Thanks for all the answers!

First, I used sleep because I didnt know better. Im no expert.

So the question was: Im at the beginning of the main loop. I check the time, I check the messages from the system, etc, and I discover that I dont need to call either render() or update() in the next 7ms. (Because my game is just a small game, or my game is Half-Life1 and its 2013 now, or my game is AAA game but Im alone on the map and looking at the ground, etc) If it was just 1-2 ms, I guess it would make sense to call update() and render() anyway. .....but for 7ms it would be better to "pause" the thread and let the CPU do whatever else it wants to do(probably nothing).

I used sleep() and on a high-end CPU it worked fine but on an other machine it produced weird effects. It was because it always woke up much later as it was expected. I also heard others say that sleep is unreliable. ....so I dont use it anymore, except when the game is paused.

("PerformanceCounter". I tried this: on one machine it returned negative values, on an other one it was going back and forth between two values. So I use it only for profiling and I use timeGetTime for the game time.)

Anyway, I thought there is a simple solution for this, but now I see there isnt. ....I think I will be OK with vsync for now.

Ive found a similar thread where they also recommend WaitForSingleObject:

http://stackoverflow.com/questions/5296990/queryperformancecounter-and-overflows

I will check that out tomorrow and re-read all your answers but now Im falling asleep, its 3:15 at night here:)

Advertisement

I may be wrong when I said Sleep() is the best way to “sleep” for a period of time.

I have never used waitable timers but they are likely the best way.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

this article may be of interest to someone:

http://randomascii.wordpress.com/2013/04/02/sleep-variation-investigated/


So the question was: Im at the beginning of the main loop. I check the time, I check the messages from the system, etc, and I discover that I dont need to call either render() or update() in the next 7ms. (Because my game is just a small game, or my game is Half-Life1 and its 2013 now, or my game is AAA game but Im alone on the map and looking at the ground, etc) If it was just 1-2 ms, I guess it would make sense to call update() and render() anyway. .....but for 7ms it would be better to "pause" the thread and let the CPU do whatever else it wants to do(probably nothing).

Just a side observation, but that reads as if you might be using unnecessarily old input. Even if you are waiting I would grab input again directly before calling update to cut down a little on latency and if not you could use that time spinning around getting input, instead of an empty loop only checking time.


I used sleep() and on a high-end CPU it worked fine but on an other machine it produced weird effects. It was because it always woke up much later as it was expected. I also heard others say that sleep is unreliable. ....so I dont use it anymore, except when the game is paused.


Was the high end machine running win 8? Win 8 waits the exact amount of time (within certain limitations) that the next sleeping thread needs to wake up, so it isn't dependent on any timer resolution like previosu versions.


("PerformanceCounter". I tried this: on one machine it returned negative values, on an other one it was going back and forth between two values. So I use it only for profiling and I use timeGetTime for the game time.)


This is pretty normal. QueryPerformanceCounter isn't reliable on all CPUS, so even if you do use it for loop timing you need to back it up with some other less precise timer (like timeGetTime()) than can let you know when QueryPerformanceCounter is grossly incorrect.



Back to L. Spiro.


I am an R&D programmer at tri-Ace, where I work on this engine:


I know, I've seen you around. I wasn't trying to make an argument from authority, I was just starting to feel that maybe you thought I was a hobbyist spouting off. Which probably backfired because then you probably thought that that was what I thought. I also do heavy lifting engine work, btw, although not on a dedicated R&D team.


Keeping this in mind, I can hardly believe you even said the following:

After all my efforts, if I were to then discover that some idiot wasted a whole millisecond of a frame sleeping for no reason, I kid you not I would punch him or her in the face. Twice.


I didn't say that, I said in the case where you already had oodles of spare CPU time. That's not "no reason", and it's not happening when that spare ms would hurt your mesh skinning because in that case there's no oodles of spare CPU cycles.

Your linked mech skinning example, btw, being one where I absolutely would never sleep, as you're on a console and know you're already sucking up every available cycle, and always will be. This though is apples and oranges, you're countering an argument I've made for games on Windows or phones with a console game. They are different environments, they have different engineering considerations.

I'm not sure if I'm not explaining things very well or what, but please try to understand what I'm saying. I am not talking about consoles. I am not talking about systems which are always just squeaking by. I am not talking about sleeping when you have no time to spare. I'm saying that battery life/heat is really, really important for usability on platforms that are inherently backwards compatible and likely to be portable. As I have said before, many times, everything you have said is absolutely, one hundred percent true, *under certain circumstances*. Console development being one of them. But I think you do hobbyists and students a great disservice by dismissing concerns that actually are part of the platforms they are most likely to be developing on.

If FTL or the Duck Tales remake were to peg my CPU at 100% while I'm running in a window (no vsync), even if they only needed 25-30% of a core to be smooth, I would be very, very sad, and would not consider that to be a good engineering decision. Likewise, as cutting edge titles age, they will also take a smaller and smaller amount of CPU time. I don't want Quake2 to be pegging my modern laptop CPU at 100% when it now only needs 10% to be smooth. It's brainless engineering to get the best of both worlds by simply not calling sleep if you don't have cycles sleep. If you want to add a checkbox to toggle this, go for it, but as a usability thing, I'd leave it limited by default.

Anyway, I think I've explained my reasons about as well as I can at this point.


Just a side observation, but that reads as if you might be using unnecessarily old input. Even if you are waiting I would grab input again directly before calling update to cut down a little on latency and if not you could use that time spinning around getting input, instead of an empty loop only checking time.

Sure. I dont call update and render right after sleep. I "restart" the loop and check the time again.


Was the high end machine running win 8? Win 8 waits the exact amount of time (within certain limitations) that the next sleeping thread needs to wake up, so it isn't dependent on any timer resolution like previosu versions.

No, that was Win7. I checked the timer resolutions and although both the Win7 machine and the laptop with XP use 15.6 by default, basic programs like google chrome, change that to 1 ms. I changed the timer res "manually" on the laptop and with only the basic programs running the CPU ran on 2.8%. ....both with 15.6, and 1ms. Maybe with 1ms it was closer to 3%, ....but I mean it didnt really make a difference.

This topic is closed to new replies.

Advertisement