Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » waiting for vsync uses up too much CPU

This thread is locked; no one can reply to it. rss feed Print
waiting for vsync uses up too much CPU
The Unknown
Member #8,441
March 2007

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
Member #1,424
July 2001

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

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

Milan Mimica
Member #3,877
September 2003
avatar

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
Member #476
June 2000
avatar

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.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Milan Mimica
Member #3,877
September 2003
avatar

Hm right, I missunderstood the code.

CGamesPlay
Member #2,559
July 2002
avatar

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.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

The Unknown
Member #8,441
March 2007

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
Member #2,559
July 2002
avatar

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

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Go to: