Love CPU usage

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
pgimeno
Party member
Posts: 3674
Joined: Sun Oct 18, 2015 2:58 pm

Re: Love CPU usage

Post by pgimeno »

Let me see if I can explain the problem better.

Let's say that your program runs at a fixed frame rate of 60 Hz without vsync, and that the monitor runs exactly at 60 Hz. Since your program is not syncing to vsync, they may be out of phase; for example, the vertical retrace may happen in the middle of your update.

Now, taking into account that the time that update and draw take can vary, this can happen:

Code: Select all


Monitor:
...--1/60 s---------------------------|-------------------------------1/60 s-------------------------------|
...-screen refresh--------------------|==v.retrace==|--------------------screen refresh--------------------|...
                                      ^                                                                    ^
                                    vsync                                                                vsync

Program (some frame):
|-------------------------------1/60 s-------------------------------|-------------------------------1/60 s-...
|Events|----Update---|--Draw--|*|----------------Sleep---------------|Events|...
                               ^
                            Present

Program (some other frame where Update and Draw take longer):
|-------------------------------1/60 s-------------------------------|-------------------------------1/60 s-...
|-Events-|----------Update---------|---------Draw--------|*|--Sleep--|-Events-|...
                                                          ^
                                                       Present
While the total frame rate is fixed, if there's something like a triple buffer the actual frame rate will be erratic, because the time between calls to present() is irregular, as it depends on the execution time of update() and draw().

That won't happen if the sleep is performed before Present(): the sleep() will complete a whole 1/60th of a second, and Present() will therefore be called at regular intervals. There will be too little time for the player to react to the current frame though, but I doubt anyone has reflexes under 17 ms anyway. https://humanbenchmark.com/tests/reactiontime

That's for a fixed frame rate. The case of frame rate limiting (i.e. to have a maximum frame rate) is more complicated, unless the video card supports adaptive vsync.

I still don't see why the events processing time should not be included in the total measurement.
RNavega
Party member
Posts: 385
Joined: Sun Aug 16, 2020 1:28 pm

Re: Love CPU usage

Post by RNavega »

pgimeno wrote: Thu Sep 03, 2020 1:59 pmI still don't see why the events processing time should not be included in the total measurement.
I don't understand the confusion, timerStep() (alias for love.timer.step()) returns the time that's elapsed since the last call to it.
So in that first code that I posted that we're talking about, when you have...

... present | timerStep B | sleep? | process_events | timerStep A | update | draw | present | timerStep B | sleep? | process_events ...

timerStep A = time taken by ( sleep?, process_events ) *
timerStep B = time taken by ( update, draw, present )

* The orange bar in that diagram.

The events processing time is included in timerStep A, as well as anything new that you might add between timerStep B ~ timerStep A. And the call to update() sends in a 'dt' of (timerStep A + timerStep B).

Edit: I should add that I'm not going to use this anymore. What you get from setting (t.conf.vsync = 2) in conf.lua not only gives a more consistent framerate and lower CPU usage by the main loop, it also simplifies the code a lot, as it's all done internally.
User avatar
pgimeno
Party member
Posts: 3674
Joined: Sun Oct 18, 2015 2:58 pm

Re: Love CPU usage

Post by pgimeno »

RNavega wrote: Sat Sep 05, 2020 8:06 am I don't understand the confusion, timerStep() (alias for love.timer.step()) returns the time that's elapsed since the last call to it.
I was wrong. The confusion came from the fact that I missed that you were waiting for the sum of both, not for only one.
crystal
Prole
Posts: 15
Joined: Sat Sep 30, 2017 9:53 pm

Re: Love CPU usage

Post by crystal »

i noticed also other opengl applications (usually cross platform) have high cpu usage on windows
gcmartijn
Party member
Posts: 146
Joined: Sat Dec 28, 2019 6:35 pm

Re: Love CPU usage

Post by gcmartijn »

Today I was testing how many images my test system can handle, so I know how many images and other things I can use.
A very simple test for now was loading and drawing images.

And I do see a CPU 90% using around 5000 small images, and don't know if that is normal.

1.
I don't know if this is a Apple device problem, and if I need to do something about this.

2.
And I'm wondering if your systems get the 'same' CPU results using the same code below, just use a very small image around 150 bytes.

Code: Select all

-----------------------------------
-- macOS Catalina macbook air 2014
-- 1.4 dual core intel i5
-- 4 GB - intel HD 5000 1536MB
-----------------------------------
-- love 11.3
-----------------------------------
-- n images | CPU  | MEM    | FPS | vsync
-----------------------------------
-- 1        | 17%  | 58 MB  |     | 0
-- 100      | 30%  | 59 MB  |     | 0
-- 1000     | 60%  | 72 MB  | 135 | 0
-- 1000     | 60%  | 72 MB  | 60  | 1
-- 5000     | 90%  | 137 MB | 41  | 0
-- 5000     | 90%  | 137 MB | 41  | 1
-----------------------------------
function love.load()
    images = {}
    for index = 0, 1000 do
        table.insert(images, love.graphics.newImage("1.png")) -- 1.png small image, 153 bytes
    end
end

function love.update(dt)
end

function love.draw()
    love.graphics.print("Current FPS: " .. tostring(love.timer.getFPS()), 10, 10)
    for _, image in pairs(images) do
        love.graphics.draw(image, 0, 0)
    end
end
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Love CPU usage

Post by grump »

5000 distinct images per frame is not only an unrealistic scenario, it is also the worst possible way to render graphics. Switching textures is expensive, and it breaks batching. Better performance can be achieved by using sprite atlases (many images in one single texture), and Quads to render them. It's more work, but it pays off if you have to draw thousands of things per frame.
gcmartijn
Party member
Posts: 146
Joined: Sat Dec 28, 2019 6:35 pm

Re: Love CPU usage

Post by gcmartijn »

lol, it is not my intention to do this in the actual game (I do use atlas images).
But I want to know what is possible in love using my system, and I don't know if there is still a cpu high usage problem.

For example, I use classes and want to know how many Objects I can create that hold some data.
It like creating a baseline start point, and to see the limits or something goes wrong during developing.
At the moment I have no idea, how many sounds/objects/images/quads/texts and other things can be loaded at 60 FPS with my system.

But now I know 5000 images is not oke for love / using this setup :)

edit:
A quick quad test CPU 17% :)

Code: Select all

function love.load()
    img = love.graphics.newImage("1.png")
    quad = love.graphics.newQuad(0, 0, 50, 50, img:getDimensions())
end
function love.draw()
    love.graphics.print("Current FPS: " .. tostring(love.timer.getFPS()), 10, 10)
    for index = 0, 5000 do
        love.graphics.draw(img, quad, 0, 0)
    end
end
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Love CPU usage

Post by zorg »

You had another glaring problem in your previous code; you were using pairs to iterate over the images in love.draw...
pairs is both horridly slow and, since you were using simple sequential numeric indices, not really appropriate to use there anyway.

i'm guessing your performance would rise tremendously even if you just replaced it with ipairs.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
gcmartijn
Party member
Posts: 146
Joined: Sat Dec 28, 2019 6:35 pm

Re: Love CPU usage

Post by gcmartijn »

-----------------------------------
-- n images | CPU | MEM | FPS | vsync
-----------------------------------
-- 1000 | 60% | 72 MB | 60 | 1 -- pairs
-- 1000 | 35% | 72 MB | 60 | 1 -- ipairs

It make a huge difference indeed, but with 5000 items (what nobody uses) no difference.

Interesting thing to optimise, maybe I have to convert some pair {tables} to ipairs array tables.
The code base is small at the moment so good to know this. Thanks

edit.

https://stackoverflow.com/questions/895 ... a-for-loop
pairs: 3.078 (217%)
ipairs: 3.344 (236%)
for i=1,x do: 1.422 (100%)
for i=1,#atable do 1.422 (100%)
for i=1,atable_length do: 1.562 (110%)

About 3% CPU if you use a for i = 1, #images do loop.

I'm aware of readable code, is for me more important but on some place I'm going to change the use of pairs into a for range or ipairs.
Here you can find some other things: https://springrts.com/wiki/Lua_Performa ... _for-loops

Code: Select all

-- 1000  | 36%  | 72 MB  | 60  | 1
    for i = 1, #images do
        love.graphics.draw(images[i], 0, 0)
    end

    -- -- 1000  | 36%  | 72 MB  | 60  | 1
    -- for i = 1, imgCount do
    --     love.graphics.draw(images[i], 0, 0)
    -- end

    -- 1000 | 39%  | 72 MB  | 60  | 1
    -- for _, image in ipairs(images) do
    --     love.graphics.draw(image, 0, 0)
    -- end
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Love CPU usage

Post by zorg »

Do realize that those benchmark PuC (Vanilla) lua; Löve by default uses Mike Pall's LuaJIT, which is highly optimized... but besides that, it also has different benchmark results: https://gitspartv.github.io/LuaJIT-Benchmarks/
And even then you shouldn't believe those stats too much; if you need to bench, do it on your own code, and see which part is slow and which is not. https://github.com/pfirsich/jprof this is a neat lib for that.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests