is it only me, or do love games seem a little cpu intensive? I've tried out multiple games on the love arcade and they seem to really eat up cpu. I've also tried out the game the people made in this topic and its not even playable on my box.
viewtopic.php?f=3&t=1609&p=15730&hilit=gamecamp#p15730
I've tried it out on the dual core computer i have at work and it seems to work, but it still has its little skips here and there.
The pc i have at home isn't all that old, it's got plenty of ram and a pentium4 processor, so what gives? this just bad programming on the developers part, or is it something specific to love2d?
Love CPU usage
Re: Love CPU usage
LÖVE tries to achieve maximum FPS at all times, which means it's going to use as much CPU as it can. The default run loop sleeps for about a millisecond every frame, but that still means it'll be eating a lot of your CPU.
The solution is to use love.timer.sleep in your love.update loop - by telling LÖVE to sleep, you remove some of the burden on the CPU. Here's a quick bit of code you can drop in your programs to help LÖVE and your CPU chill out:
Then just make the last line of love.update "sleep(dt)" and your program will relinquish any CPU time it doesn't need, hopefully giving your machine a bit of a breather. Note that if your program drops below its FPS cap, it's still going to be running full throttle.
The solution is to use love.timer.sleep in your love.update loop - by telling LÖVE to sleep, you remove some of the burden on the CPU. Here's a quick bit of code you can drop in your programs to help LÖVE and your CPU chill out:
Code: Select all
FPSCAP = 60 -- change if you want higher/lower max fps
function sleep(dt)
local s = 1/FPSCAP - dt
if s > 0 then love.timer.sleep(s*1000) end
end
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Love CPU usage
I kind of assumed that this was done automatically by LÖVE!
I'll apply this little piece of code to PÄSSION inmediately.
I do believe that LÖVE should come with a default "relinquish the cicles I don't need" mechanism installed by default.
I'll apply this little piece of code to PÄSSION inmediately.
I do believe that LÖVE should come with a default "relinquish the cicles I don't need" mechanism installed by default.
When I write def I mean function.
Re: Love CPU usage
Doesn't LÖVE have a vsync toggle? That should do the trick, right?
- bartbes
- Sex machine
- Posts: 4946
- Joined: Fri Aug 29, 2008 10:35 am
- Location: The Netherlands
- Contact:
Re: Love CPU usage
It's on by default, I guess his video card/driver doesn't support vsync.
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Love CPU usage
Well I'm pretty sure my card admits vsync and I still notice lots of cpu usage (haven't applied anjo's code yet)
When I write def I mean function.
Re: Love CPU usage
I would like to point out that Anjo's code does not work reliably. Here is a corner case that shows how badly it can go wrong; it is demonstrated by the first code block below. Granted, the FPSCAP of five is unrealistic, but it gives you enough time to see the lengths of frames on screen in real time. It also shows that despite the cap, the program can run at up to 10 FPS (which is exactly what happens on this computer I am on). This is not what I ask the program to do when I put the 5 in there.
You can also try running this with a higher FPSCAP. Turn off vsync and log the times it takes to run each frame, and you'll probably see a pattern where occasional very short frames appear between the frames of expected length. This is because going over the limit for one frame lets the program logic run the next frame as fast as possible. I get a result of about 102 FPS when I ask for 60 and set vsync off in conf.lua!
It would be better to have a solution that resulted in approximately equal length frames in any case, both under high load and low load from other processing in the game. And it should not depend on vsync, which can't be guaranteed to be usable on every computer your game might run on. I'm afraid this is not it:
This one has better behavior in this corner case. However, does it work so well with higher FPS and no vsync, and higher loads from other game logic? The timer granularity on some systems can also be an issue.
You be the judge! But remember that a good solution should be demonstrably a good solution--and in all cases you might encounter.
Again, note that FPSCAP = 5 comes from wanting to read the output in real time!
In a real program, you should start keeping track of lastframe when the game actually begins, of course. It does you no good to know the first one lasted 30 seconds or whatever it takes for the game to load completely
You can also try running this with a higher FPSCAP. Turn off vsync and log the times it takes to run each frame, and you'll probably see a pattern where occasional very short frames appear between the frames of expected length. This is because going over the limit for one frame lets the program logic run the next frame as fast as possible. I get a result of about 102 FPS when I ask for 60 and set vsync off in conf.lua!
It would be better to have a solution that resulted in approximately equal length frames in any case, both under high load and low load from other processing in the game. And it should not depend on vsync, which can't be guaranteed to be usable on every computer your game might run on. I'm afraid this is not it:
Code: Select all
FPSCAP = 5 -- change if you want higher/lower max fps
local lastframe = nil
local diffs = {}
local LINES = 25
function love.update(dt)
local s = 1/FPSCAP - dt
if s > 0 then love.timer.sleep(s*1000) end
if lastframe then
local now = love.timer.getMicroTime()
table.insert(diffs, now - lastframe)
end
lastframe = love.timer.getMicroTime()
if #diffs > LINES then table.remove(diffs, 1) end
end
function love.draw()
love.graphics.print('FPS: ' .. love.timer.getFPS(), 20, 20)
for i = 1, #diffs do
love.graphics.print(tostring(diffs[i]), 20, 20+i*20)
end
end
You be the judge! But remember that a good solution should be demonstrably a good solution--and in all cases you might encounter.
Code: Select all
FPSCAP = 5 -- change if you want higher/lower max fps
local lastframe = nil
local diffs = {}
local LINES = 25
function love.load()
lastframe = love.timer.getMicroTime()
end
function love.update(dt)
local slack = 1/FPSCAP - (love.timer.getMicroTime() - lastframe)
if slack > 0 then love.timer.sleep(1000*slack) end
local now = love.timer.getMicroTime()
local diff = now - lastframe
lastframe = now
table.insert(diffs, diff)
if #diffs > LINES then table.remove(diffs, 1) end
end
function love.draw()
love.graphics.print('FPS: ' .. love.timer.getFPS(), 20, 20)
for i = 1, #diffs do
love.graphics.print(tostring(diffs[i]), 20, 20+i*20)
end
end
In a real program, you should start keeping track of lastframe when the game actually begins, of course. It does you no good to know the first one lasted 30 seconds or whatever it takes for the game to load completely
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: Love CPU usage
It does. It tells you you need to change your game loading code.pekka wrote:In a real program, you should start keeping track of lastframe when the game actually begins, of course. It does you no good to know the first one lasted 30 seconds or whatever it takes for the game to load completely
Help us help you: attach a .love.
Re: Love CPU usage
Fair enough, Robin, though you might have your game start slower because you start it from a network drive
I'd like to add that there is a rather unlikely possibility of failure in my code too.
I don't know how exactly the results of getMicroTime wrap around, or if they do, but suppose they do so in a way that results in the parenthesized expression becoming a large negative number. The subtraction will flip its sign, and this will result in your game sleeping for a long time. That will be one frame to remember!
So, for extra paranoia, check the slack value for some reasonable upper bound too:
I suppose you are not ever going to want to sleep longer than 1/FPSCAP, for example, so it might be a good value for the LIMIT. Now, the docs say the result of getMicroTime is limited to 24 hours, so this little bit of code might be needed once every 24 hours your game runs in one go. Ha ha.
This topic would deserve a bit more thorough analysis and explanation, and cleaner sample code, and when I have the time for it, I'll see if I can put up a reasonable Wiki page. (Or improve an existing page, if the topic already exists.)
I'd like to add that there is a rather unlikely possibility of failure in my code too.
Code: Select all
local slack = 1/FPSCAP - (love.timer.getMicroTime() - lastframe)
if slack > 0 then love.timer.sleep(1000*slack) end
So, for extra paranoia, check the slack value for some reasonable upper bound too:
Code: Select all
-- not tested, just typed in the forum
if slack > 0 and slack < LIMIT then love.timer.sleep(1000*slack) end
This topic would deserve a bit more thorough analysis and explanation, and cleaner sample code, and when I have the time for it, I'll see if I can put up a reasonable Wiki page. (Or improve an existing page, if the topic already exists.)
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Love CPU usage
I'm definitively interested on that. The single thing that worries me about LÖVE is the processor - it's starting up a game and it goes up very quickly.
I'm watching this thread - please comment here it if/when you do your research.
I'm watching this thread - please comment here it if/when you do your research.
When I write def I mean function.
Who is online
Users browsing this forum: No registered users and 2 guests