Page 1 of 1

delay in love.run()

Posted: Thu Jan 16, 2014 7:28 am
by AntonioModer
Why use this delay in love.run()? (http://www.love2d.org/wiki/love.run)

Code: Select all

if love.timer then love.timer.sleep(0.001) end
This reduces the speed of execution!
My guess: Maybe, for the timer to work with high accuracy?

Re: delay in love.run()

Posted: Thu Jan 16, 2014 8:22 am
by Plu
I believe it's to give control back to the Operating System so it doesn't forcefully cut your program short whenever it feels like it. But the devs can probably explain it better :)

Re: delay in love.run()

Posted: Thu Jan 16, 2014 8:50 am
by slime
It does a few things:
- Limits FPS to 1000 if vsync isn't enabled.
- Massively reduces CPU usage in many situations (especially with vsync disabled.)
- gives control back to the OS for a bit, as Plu mentioned.

It's (in theory) a 1-millisecond CPU-side sleep per frame. 60 FPS (the refresh rate of a typical monitor) is 16.6 milliseconds per frame, so in reality the sleep isn't using much of the total CPU time you have available to maintain 60 FPS (and it doesn't sleep the GPU - keep in mind the GPU runs asynchronously as well, so sleeping the CPU won't slow down the GPU if you're GPU-bound.)

Re: delay in love.run()

Posted: Thu Jan 16, 2014 9:32 am
by veethree
Out of curiosity, what's the purpose of the 1000 fps limit? Not that 1000 fps isn't enough.

Re: delay in love.run()

Posted: Thu Jan 16, 2014 10:10 pm
by BoopDeePoop
veethree wrote:Out of curiosity, what's the purpose of the 1000 fps limit? Not that 1000 fps isn't enough.
There has to be some sort of set limit to the frames that you can get.

Re: delay in love.run()

Posted: Fri May 13, 2016 8:07 pm
by mode7
Sorry for bumping this old thread, but I guess it's the right place to post this, since it's even linked in the wiki.

I got really interested in this explanation, as it obviously works for LÖVE even though it absolutely shouldn't (!).

I played around with SDL a bit lately and ran into the same issue with my game loop eating up the whole CPU core.
I had a look a the LÖVE2D source code and saw that love.timer.sleep looks like this:

Code: Select all

void Timer::sleep(double seconds) const
{
	if (seconds > 0)
		love::sleep((unsigned int)(seconds*1000));
}
Which in turn just calls an SDL function

Code: Select all

void sleep(unsigned int ms)
{
	SDL_Delay(ms);
}
This means love.timer.sleep(0.001) translates to: SDL_Delay(1)

The problem is, that this won't actually wait for 1ms, but more likely for about 10ms, as stated here:
https://www.libsdl.org/release/SDL-1.2. ... delay.html
Note: Count on a delay granularity of at least 10 ms. Some platforms have shorter clock ticks but this is the most common.


This is also exactly how SDL will behave in my tests, dropping the framerate signifcantly bellow 1000 fps (more like 75)
OS specific calls to Thread.Sleep behave the same way, so WHY is this working for LOVE?

It would be great if some of the Devs would shed some light on this.

Re: delay in love.run()

Posted: Fri May 13, 2016 8:43 pm
by slime
The SDL 1.2 docs don't reflect how SDL 2.0 works (and those docs don't really reflect modern operating systems anyway – SDL 1.2 was released a decade and a half ago). LÖVE has used SDL 2.0 since version 0.9.0. :)

SDL 2.0 also makes sure to set the Windows sleep timer period to 1ms.

Re: delay in love.run()

Posted: Fri May 13, 2016 9:13 pm
by mode7
Thanks for the insightfull explanation. I guess setting the OS specific sleep period makes all the difference.

As it turns out I was using an outdated version of SDL2. Replaced it with the one from LÖVE and it works like a charm.

I'm still not sure if the period will always result to exactly 1ms as the SDL doc just implies it might not be reliable and might return more.
So I eventually ended up enforcing VSYNC which seems like a much safer choice - at least for me.