WTD: Info on getting a specific framerate without eating CPU?

I’m working on the SDL version of Stella, an Atari 2600 emulator. The
problem I’m having is in the way the framerate code is written. Below is
some pseudocode for it:

for( ; ; ++numberofframes)
{
get time before starting
update frame and check events
get time after finishing

if(there is time left until next frame)
tight loop repeatedly getting time and rechecking
}

The problem of course is that this code busywaits and eats all the CPU.
I tried, instead of the tight loop rechecking the time, to wait the
specified amount of time (with SDL_Delay, select, or usleep), but because
of the 10ms timer limitations that were discussed in previous threads,
this results in 50 (or 100) fps.

What I’m looking for are some pointers on how to get a certain framerate
without the excessive CPU usage. I’ve looked at other code that seems
to accomplish it, most notably, gngb (an SDL gameboy emulator), and to be
honest, I couldn’t figure it out :frowning:

I don’t need specific code here, but just an algorithm of how I would go
about doing it. Or some reference I should read?? Any help greatly
appreciated.

Thanks,
Steve

Stephen Anthony wrote:

I’m working on the SDL version of Stella, an Atari 2600 emulator. The
problem I’m having is in the way the framerate code is written. Below is
some pseudocode for it:

for( ; ; ++numberofframes)
{
get time before starting
update frame and check events
get time after finishing

if(there is time left until next frame)
tight loop repeatedly getting time and rechecking
}

The problem of course is that this code busywaits and eats all the CPU.
I tried, instead of the tight loop rechecking the time, to wait the
specified amount of time (with SDL_Delay, select, or usleep), but because
of the 10ms timer limitations that were discussed in previous threads,
this results in 50 (or 100) fps.

What I’m looking for are some pointers on how to get a certain framerate
without the excessive CPU usage. I’ve looked at other code that seems
to accomplish it, most notably, gngb (an SDL gameboy emulator), and to be
honest, I couldn’t figure it out :frowning:

I don’t need specific code here, but just an algorithm of how I would go
about doing it. Or some reference I should read?? Any help greatly
appreciated.

Thanks,
Steve


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

you could wait for the time left minus 10ms or so, and then busy wait for the actual time left after that…–
-==-
Jon Atkins
http://jonatkins.org/

Stephen Anthony wrote:

What I’m looking for are some pointers on how to get a certain framerate
without the excessive CPU usage.

On most platforms, you can’t sleep for shorter than 10 ms. This means
that if you can stand having some frames shorter and others longer
than what you want, as long as the average matches your desired
framerate, then just do something like

loop:
emulate()
next_frame += frame_interval
now = SDL_GetTicks()
delay = next_frame - now
if delay >= 10 ms: /* or some other constant */
SDL_Delay(delay)

If you need more precise timing, you either need to busy-wait or use
a platform-dependent timer (under linux, read the docs on /dev/rtc or
rebuild your kernel with HZ=1000 (not for the beginner))

Note that most real-time games eat 100% cpu so this is not necessarily
a bad thing in itself. Emulators sometimes link their speed to audio
output for various reasons

What I’m looking for are some pointers on how to get a certain
framerate without the excessive CPU usage. I’ve looked at other
code that seems to accomplish it, most notably, gngb (an SDL gameboy
emulator), and to be honest, I couldn’t figure it out :frowning:

you could wait for the time left minus 10ms or so, and then busy wait
for the actual time left after that…

Thanks for the info. Unfortunately, since the emulator will run at 60
fps most of the time, that translates to 16.67 ms / frame. Since
updating the frame and checking events usually takes a bit longer than
16.67 - 10 ms, the time I should wait is less than 10ms. But I can’t
wait for less than 10 ms, and thats why the framerate drops :frowning:

SteveOn January 19, 2002 01:29 pm, you wrote:

Stephen Anthony wrote:

What I’m looking for are some pointers on how to get a certain
framerate without the excessive CPU usage.

On most platforms, you can’t sleep for shorter than 10 ms. This means
that if you can stand having some frames shorter and others longer
than what you want, as long as the average matches your desired
framerate, then just do something like

loop:
emulate()
next_frame += frame_interval
now = SDL_GetTicks()
delay = next_frame - now
if delay >= 10 ms: /* or some other constant */
SDL_Delay(delay)

First of all, thanks for the info. Unfortunately, I did try something
similar to that and the change in framerate was apparent. I could notice
even a 3 fps difference :slight_smile:

If you need more precise timing, you either need to busy-wait or use
a platform-dependent timer (under linux, read the docs on /dev/rtc or
rebuild your kernel with HZ=1000 (not for the beginner))

I will look into this. Maybe I could make it a compile-time option.

Note that most real-time games eat 100% cpu so this is not necessarily
a bad thing in itself. Emulators sometimes link their speed to audio
output for various reasons

OK, thats what I thought. Its just that I’ve seen some other emulators
that seem to not busy-wait and still keep the correct frame rate correct.
Some users requested that I add the non busy-wait feature, but if its too
difficult I’ll leave it alone for now.

Thanks,
SteveOn January 19, 2002 01:43 pm, you wrote: