Page 1 of 1

Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 3:24 am
by Desent
(sorry, i bad know english)

Code: Select all

function love.load()
	news = {}
	delay = 10
	width = love.graphics.getWidth()
end

function love.update(dt)
	if delay > 0 then
		delay = delay - dt
	else
		table.insert(news, 1, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin in porta nunc. Donec condimentum porttitor faucibus.")
		delay = 10
	end
end

function love.draw()
	love.graphics.printf(table.concat(news,"\n"), 30, 20, width - 300, "left") --bad code, load cpu
	
	---AND OTHER VARIANTS LOAD CPU TOO---
	--love.graphics.print(news, 30, 20) --bad code, load cpu
	--love.graphics.printf(news, 30, 20, 1000, "left") --bad code, load cpu
	--love.graphics.printf(table.concat(news,"\n"), 30, 20, 1000, "left") --bad code, load cpu
	
	--for i in pairs(news) do
	--	love.graphics.print(news[i], 30, 15 * i) --bad code, load cpu
	--end
	--for i in pairs(news) do
	--	love.graphics.print(tostring(news[i]), 30, 15 * i) --bad code, load cpu
	--end
	
	love.graphics.print(#news, 1, 220)
end

Re: Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 6:47 am
by airstruck
Does it make any difference if you store news as a string instead of a table, and concatenate to it in love.update?

What about the Text drawable, does that put less load on the CPU?

Re: Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 8:35 am
by Desent
airstruck wrote:Does it make any difference if you store news as a string instead of a table, and concatenate to it in love.update?

What about the Text drawable, does that put less load on the CPU?
Concatenate in love.update load CPU too.

I don't want use drawable text.

But, if previously add(print) long string in love.draw, then load on cpu will 2-3%(normal level). Wtf???

Code: Select all

function love.load()
	news = {}
	--newsString = nil
	delay = 10
	width = love.graphics.getWidth()
end

function love.update(dt)
	if delay > 0 then
		delay = delay - dt
	else
		table.insert(news, 1, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin in porta nunc. Donec condimentum porttitor faucibus.")
		delay = 10
		--newsString = table.concat(news,"\n")
	end
	if #news > 5 then
		table.remove(news, 6)
	end
end

function love.draw()
	love.graphics.print("Nunc varius gravida quam, vel facilisis quam fringilla eget. Donec suscipit aliquet erat non pretium. Mauris fringilla posuere dui, a ultrices turpis venenatis in.", 100, 200)

	love.graphics.printf(table.concat(news,"\n"), 30, 20, width - 500, "left")
	
	--if newsString ~= nil then
		--love.graphics.printf(newsString, 30, 20, width - 500, "left") --bad code, load cpu
	--end
	love.graphics.print(#news, 1, 200)
end

Re: Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 9:37 am
by airstruck
That's really strange. If I had to guess, I'd guess it's forgetting to cache the texture atlas for some reason, and having to regenerate it every time, but somehow adding the other print() call gets the texture atlas to cache properly.

Re: Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 2:58 pm
by Germanunkol
Desent wrote:Why this simple code load cpu to 30%?
The reason for the CPU load is most likely that the program will run "as fast as possible". No matter how simple the operations within one frame are, after the frame has been rendered, the program starts again straight away with the next loop. This has nothing to do with your code:
For me, even this code uses 30% of a CPU:

Code: Select all

function love.load()
end

local i = 0
function love.update(dt)
	i = i + 1
end

function love.draw()
   love.graphics.print( i, 10, 10 );
end
The only way you can really compare these things is if you check out how many frames per second the engine renders. Try placing this line in your love.draw function:

Code: Select all

love.graphics.print( love.timer.getFPS(), 10, 10 );
You'll see that the number of frames rendered per second is very, very high (multiple hundred?), meaning that your code gets executed a lot of times per second. If you do more calculations in the update loop, a frame will take longer to process and thus the number of frames per second will decrease, but you'll probably still get a high CPU load.

Note: With a simple program like your example, one could actually expect an even higher CPU load (like 100%), because, as I mentioned, the new frame starts just after the last frame has finished.
I expect the reason why the CPU load is "only" at 30% is that the rest of the time, the CPU is waiting for the graphics card to finish rendering the frame - but that's just a guess.

Edit Tl;dr: To get an idea about how fast the code pieces are, compare the Frames Per Second between the different versions, _not_ the CPU load.

Re: Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 4:38 pm
by airstruck
Shouldn't we assume OP has vsync on? Doesn't Love sleep for a bit to avoid maxing out the CPU? Aside from that, how would just one extra print explain such a major reduction in CPU load? It doesn't sound like an issue with OP's code to me.

Re: Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 4:50 pm
by slime
Some implementations of vsync do a busy-wait instead of a sleep (and some do a sleep *and* a busy-wait, I believe).

Re: Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 9:11 pm
by pgimeno
With the given example, my CPU usage (of a single core) is at ~4% at the start and reaches ~10% when the counter reaches 25.

CPU: Intel Core i3-2100 @ 3.10GHz
GPU: nVidia GeForce 210, driver version: 340.96

Re: Why this simple code load cpu to 30%?

Posted: Thu Jul 28, 2016 9:56 pm
by Desent
pgimeno wrote:With the given example, my CPU usage (of a single core) is at ~4% at the start and reaches ~10% when the counter reaches 25.

CPU: Intel Core i3-2100 @ 3.10GHz
GPU: nVidia GeForce 210, driver version: 340.96
Vsync is on? If not, enable vsync in conf.lua and try launch my code again.

If i use vsync, then load on cpu >30%. But if use this small code: love.timer.sleep(1/70) without vsync, then fps = 61-62, and load on cpu <3%.

Code: Select all

function love.load()
	news = {}
	delay = 10
	width = love.graphics.getWidth()
end

function love.update(dt)
	love.timer.sleep(1/70)

	if delay > 0 then
		delay = delay - dt
	else
		table.insert(news, 1, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin in porta nunc. Donec condimentum porttitor faucibus.")
		delay = 10
	end
	--if #news > 5 then
	--	table.remove(news, 6)
	--end
end

function love.draw()
	love.graphics.printf(table.concat(news,"\n"), 30, 20, width - 500, "left")
   
	love.graphics.print(#news, 1, 200)
	love.graphics.print(love.timer.getFPS(), 1, 230)
end
My cpu: intel core i5-3337u, 1.8-2.7ghz
gpu: nvidia geforce gt740m
Windows 10

Re: Why this simple code load cpu to 30%?

Posted: Fri Jul 29, 2016 2:41 am
by pgimeno
In my case, vsync is default, which is true, i.e. enabled.

With vsync disabled, it starts on 10% and reaches 50% when there are 25 copies of the text. I interpret that as the 25 printf's taking 1ms time. The default love.run sleeps for 1ms, so it's 50% of the time sleeping and 50% printf'ing.
Desent wrote:If i use vsync, then load on cpu >30%
See what slime said. That seems to be the cause. It looks like your system does a busy-wait for vsync, sucking CPU. My system Is Linux. Is yours Linux too? What driver version?