Log In  


Working on my game, I often find myself wondering how much cpu such or such construct uses.
I do my benchmarks using stat(1).
Issue is, my measures are all over the place according to the number of samples :[

Ex: Let's bench band vs. % and shr vs / @ 100 calcs/update

Good, % is almost free, / is slightly better than shr
Let's try 200:

Hu? shr is now better than /

Push it to 300:

Back to "normal"

400:

WTF?

How come number of samples for a given run is turning results upside down?
Note: if I push number of iterator further, I tend to have stable results - but who's performing 5000% per update cycle?!?
On top of that, @zep, we should be provided with op cost of basic operations (similar to cpu specs).

Reference code:

function bench(name,n,fn)
	local t0=stat(1)
	for i=1,n do
		fn(i)
	end
	return {name,(stat(1)-t0)}
end
function stat2pct(s)
	return flr(1000*s)/10
end
function bench_draw(name1,stat1,name2,stat2,y)
	print(name1.." vs. "..name2,1,y,7)
	y+=6
	local total=stat1+stat2
	local pct1,pct2=stat1/total,stat2/total
	local c1,c2=8,11
	if(stat1<stat2) c1=11 c2=8
	local x=flr(128*pct1)
	rectfill(0,y,x+1,y+6,c1)
	x+=1
	print(stat2pct(stat1),x/2,y+1,0)
	local x2=128*pct2
	local msgx2=x+x2/2
	if(x2<1) then
		x=127 x2=127 msgx2=120
	end
	rectfill(x,y,x+x2,y+6,c2)
	print(stat2pct(stat2),msgx2,y+1,0)
	y+=8	
	return y
end

local res={}
local n=100
function _update60()
	if(btnp(0)) n-=100
	if(btnp(1)) n+=100
	n=max(n,100)

	res={}
	add(res,bench("band",n,function()
		j=band(546,127)
	end))
	add(res,bench("%",n,function()
		j=546%128
	end))

	add(res,bench("shr",n,function()
		j=90/8
	end))
	add(res,bench("/",n,function()
		j=shr(90,3)
	end))
end

function _draw()
	cls(0)

	rectfill(0,0,127,6,1)
	print(n.." iterations - \139\145 to change",1,1,7)

	local y=9
	for i=1,#res,2 do
		y=bench_draw(res[i][1],res[i][2],res[i+1][1],res[i+1][2],y)
	end
end


In 0.1.10c, certain operations have negative cost. See this thread: https://www.lexaloffle.com/bbs/?tid=29318, and in particular this demo cart: https://www.lexaloffle.com/bbs/?pid=40734#p40733


BTW, this is not an artefact of fixed-point precision, but rather the ad-hoc way PICO-8 does accounting, where some operations have positive cost, some have negative cost, and 1024 is added to the stat value every so often (based on the Lua bytecode instruction count, not PICO-8 commands, so it's difficult to predict). I think zep may be planning to clean some of this up in an upcoming release.


1

Just saw the other thread - framerate can be completely cheated using this single line:

 for i=0,32000 do
   bnot(bnot(bnot(bnot(bnot(bnot(bnot(1)))))))
   bnot(bnot(bnot(bnot(bnot(bnot(bnot(1)))))))
 end

I can now spawn gazillion of scaled sprites at 60fps!!
Question: is this exploit going to be fixed?

Edit: removed strong wording


There's not much admitting necessary. What's necessary is for zep to finish and release the next version, which, uh... doesn't seem to be happening... :/

Feature creep is dangerous, yo. :)


By the way, if you want to time individual operations, I posted a simple test rig here that gives pretty accurate pseudo-cycle counts:

https://www.lexaloffle.com/bbs/?pid=42604#p42604



[Please log in to post a comment]