waiting for vsync uses up too much CPU
The Unknown

Well, my monitor refresh rate: 60Hz
Game logic: 60Hz

Therefor, waiting for vsync uses up most extra free time there might be. A quick glance at the allegro source reveals that the code just loops within itself until theres a vertical blank, like this:

struct GFX_DRIVER {
     vsync();
};

...

GFX_DRIVER* gfx_driver;

then when you call vsync()

it does this:

void vsync(void)
{
   ASSERT(gfx_driver);

   if (!_dispsw_status && gfx_driver->vsync)
      gfx_driver->vsync();
}

So pretty much, if we're not at a vertical blank, run the function again.
Does that mean, i could slip in a rest(0) here, and get some CPU back, or would that mess everything up? Or have i just got lost in the source and completely missed something?

Kris Asick

Why not slip in a rest(1) and give even more time back to the CPU?

This is what I had to do awhile back to get around some I/O issues I had been having with Allegro 4.2.0, Windows 98, and particular hardware configurations. Actually, I'm using the Windows command Sleep() directly instead of having Allegro call it since I've stopped using the Allegro timer system by default. In either case, I call it once per logic loop, so if the game is running 60 FPS, it will give up 60 of 1000 ms back to the CPU per second. (And thus, the lower the framerate, the less time the game gives up.)

You should ALWAYS call at least rest(0) in a game loop so that background tasks don't stall-out. I recommend rest(1) to further reduce CPU usage and to get around the problem I mentioned above.

The point in your code where you call it is pretty much up to you, but never call it immediately after vsync(). (You should always blit the screen immediately after a call to vsync().)

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Milan Mimica

Implementation of vsync() in allegro should not busy-wait if timer has been installed. Try calling install_timer() first and check if it happend again. If it does, tell us which GFX_dirver are you using.

Thomas Fjellstrom

Milan, any call to install_int* will call install_timer() if it hasn't already been called. The mouse subsystem uses that fact as well.

Milan Mimica

Hm right, I missunderstood the code.

CGamesPlay
Quote:

struct GFX_DRIVER {
     vsync();
};

Where do you see that? I see this:

GFX_DRIVER gfx_directx_accel =
{
   gfx_directx_sync,
};

And that function is here:

void gfx_directx_sync(void)
{
   IDirectDraw2_WaitForVerticalBlank(directdraw, DDWAITVB_BLOCKBEGIN, NULL);
}

Alternatively, if you are using GDI:

static void gfx_gdi_vsync(void)
{
   WaitForSingleObject(vsync_event, INFINITE);
}

In fact, your code doesn't even make sense, because it would recurse as quickly as possible, which would crash almost instantly.

The Unknown

I simplified it a little, but the code i found was rather different. :-/
i think i found some of it in gfx.h and gfx.c, but im not sure where the rest is now... oh well.

CGamesPlay

Well, you're going to need to post a program with a few lines as possible that uses extensive CPU and vsync.

Thread #590675. Printed from Allegro.cc