The game loop and CPU resources...

Started by
16 comments, last by GameDev.net 19 years, 4 months ago
At this point, I have read a few game programming books and I see that most games they depict consist of a loop which runs indefinetly until the game finishes, e.g.:

  while(gameon)
  {
   figure->eraseShape();

   if(keypressed())
    getInput();

   updateWorld();

   drawWorld();

   drawText();

   rest(10);
  }


The issue I am curious about are the resources that such a loop consumes. The above code is for a tetris clone which I made some time ago. Everytime I run this game, the CPU usage shoots through the roof. Should such a simple game be so processor intensive? It seems like the better solution might be to code multiple threads, each being called at asynchronously at some specified time, yet such an approach yields very unpredictable code due to scheduling issues (and is a pain in the ass to program). How does one make such games more processor efficient?
Advertisement
Normally, you would cap your FPS to a certain value, calculate how much time is remaining till the next frame, and sleep for the appropriate amount of time, in order to free up the spare processor time.

- Jason Astle-Adams

So you would do something like the following? (just paraphrasing)

float start_time; while (1) {   start_time = time(NULL);  /* Game Code*/   rest(30-(time(NULL)-start_time)); }
if its a full screen game then use all the CPU time you need, if its a windowed game then again use all the CPU time you need and shove a sleep(0) or sleep(1) at the end of the main loop to yeild to let windows know that its free to do something else.

If you're a single player game and you lose focus then worry about the resources you take (either pause the game, or reduce CPU overhead somehow) and if you are an MP game then just keep your network pump going so the game doesnt fall over and die.

Artifical limiting of the fps however is a plan which is, imo at least, very daft.
While it is true that you usually don't need to worry too much about how much resources your game is using as long as it has focus, it is perfectly reasonable to cap the frame rate. Mike McShaffy even uses it in the examples in his book "Game Programming Complete". You definately shouldn't cap the frame rate so low that it hurts the performance of your game, but there's really no reason to have a framerate above 60fps. Firstly, your eye can't tell the difference much beyond that point. Secondly, most video cards can't refresh the screen faster than that anyway (although some video modes are a bit faster).
Quote:Original post by nimrand
...


What he said.

- Jason Astle-Adams

first point; dont mention fps rates and eyes around here, it leads to arguements (and for the record the eyes dont see in discrete frames anyways so the mesurement is meaningless), however I'll just point out that at 60fps I get a head/eyeache at 72fps I can get along just fine, guess what refresh rate i force on my monitor [smile] now, you cap your game at 60fps opps, my display is now choppy (some frames displayed twice, some not) unless I bring my v-sync rate back down to 60hz at which point I end up in pain... no fun [smile] (and i'm not alone in this respect)

2nd point; bollox. Depending on the complexity of the scene they can do anything from 1frame per hour to over 100fps and beyond, its depends on the amount of work you make the gfx card do AND the amount of work the CPU has todo.

So, I say again, capping frame rates imo is daft, use v-sync if you are going to cap at all at least then you'll be locked to what the monitor is displaying.
Well, it would seem that the topic of Framerate limiting is more contested that I would have imagined. :)

The thing that I wanted to make sure happened was that the tetris-clone worked at the same speed no matter on which computer it is played on. Although minimal, the difference can be felt when played on differnt computers. My initial question was trying to find a way to implement this game loop efficiently such that the CPU's speed would not affect gameplay (withing reason, of course). Surely tetris can run just as well on a 400 Mhz processor as on a 2.6 GHz.
Quote:Original post by _the_phantom_
if its a full screen game then use all the CPU time you need, if its a windowed game then again use all the CPU time you need and shove a sleep(0) or sleep(1) at the end of the main loop to yeild to let windows know that its free to do something else.


I'm not sure, but wasn't that necessary in the days of Win3.x or something? After Windows95, you don't have to "pass" the CPU to Windows, every process gets a chunk of time anyway. The only thing he needs to do is to dispatch the messages every now and then, so the message queue don't get overflowed.

And for fps capping, it's not very good idea, let vsync handle that. In either case, it's good practice to use the extra time to perform CPU calculations(physics,AI...), and not just waste it with sleep().

-EDIT: I just saw now that sleep() "causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run". So if your app is not multithreaded, there's no reason to use it.
Quote:Original post by TheWanderer
Well, it would seem that the topic of Framerate limiting is more contested that I would have imagined. :)

The thing that I wanted to make sure happened was that the tetris-clone worked at the same speed no matter on which computer it is played on. Although minimal, the difference can be felt when played on differnt computers. My initial question was trying to find a way to implement this game loop efficiently such that the CPU's speed would not affect gameplay (withing reason, of course). Surely tetris can run just as well on a 400 Mhz processor as on a 2.6 GHz.


For this, instead of moving the block down by say 2 units every time the updateWorld function is called, simply movie it down by 2 units times the ammount of time since the last time the block was moved. Example:

do not do:
block.y -= 2;

instead do:
block.y -= 120 * time_since_last_frame;

you will need to apply this to all places where something happens every frame with some consant value. That constant value should be scaled by the amount of time elapsed.

Hope I've helped!

This topic is closed to new replies.

Advertisement