Worrying CPU usage? What am I missing?

BlitzMax Forums/MiniB3D Module/Worrying CPU usage? What am I missing?

Yasha(Posted 2009) [#1]
Hi all. I'm very new to BlitzMax and miniB3D, and I thought I'd copy over a test program from Blitz3D. After some whittling down I ended up with this:


Framework sidesign.minib3d

Global appheight=768
Global appwidth=1024
Global appdepth=32



SC_FPS=60	'Desired framerate
rtime=Floor(1000.0/SC_FPS)
limited=True

Graphics3D appwidth,appheight,appdepth,2
'Graphics appwidth,appheight

centrecam=CreatePivot()
PositionEntity centrecam,0,15,0
camera=CreateCamera(centrecam)
PositionEntity camera,0,20,-50,1

sun=CreateLight()
PositionEntity sun,-100,400,0
PointEntity sun,centrecam

ground=CreateMesh()
'parquet=CreateSurface(ground)
'v1=AddVertex(parquet,-125,0,150);v2=AddVertex(parquet,125,0,150);v3=AddVertex(parquet,125,0,-100)
'AddTriangle(parquet,v1,v2,v3);v2=AddVertex(parquet,-125,0,-100);AddTriangle(parquet,v1,v3,v2)
'EntityColor ground,0,0,255
'block=CreateCube();ScaleMesh block,20,5,20



While Not KeyDown(KEY_ESCAPE)
'	ctime=MilliSecs()

'	MoveEntity camera,0,VKeyDown(200)-VKeyDown(208),VKeyDown(30)-VKeyDown(44)
'	TurnEntity centrecam,0,VKeyDown(203)-VKeyDown(205),0
'	MoveEntity centrecam,0,(VKeyDown(31)-VKeyDown(45))*0.2,0
'	PointEntity camera,centrecam
	
'	If VKeyHit(38) Then limited=Not limited					'Turn off frame limit
	
'	If MilliSecs()-render_time=>1000 Then fps=frames;frames=0;render_time=MilliSecs();Else frames=frames+1
	
'	UpdateWorld
	RenderWorld
	
'	Text 0,30,"FPS: "+fps
	
'	n=rtime-(MilliSecs()-ctime)		'Free spare CPU time
'	Delay n-(limited+1)
	
	Flip' limited
Wend

End



As far as I'm aware it's essentially a straight copy of this Blitz3D code:



There is however a difference. The Blitz3D version works as expected - and with a minimum of CPU use thanks to a strategically-positioned Delay command. But this doesn't seem to work in the BlitzMax/miniB3D version. (I have no idea whether BlitzMax requires Delay commands in order to even things out, but I didn't see it making a difference no matter which lines were commented.) As you can see everything is removed from the loop except RenderWorld - and CPU usage sits at 50%. If I remove RenderWorld, CPU usage drops to 0-2% (this is watching it in Task Manager). If I leave RenderWorld but remove the camera, the same applies. If I remove the lines that add meshes to render, but leave the camera and light, CPU generally sits around 3% but sometimes spikes to 30% or more. Removing the light lowers the spikes a little. Finally, creating the camera, creating a mesh without surfaces and calling RenderWorld plants the CPU usage firmly back at 50%.

As I stated at the beginning, commenting and uncommenting the Delay lines has no noticeable effect. And this exact same program in Blitz3D runs with CPU usage at 7-8%. So what's going on? Is this a general BlitzMax thing, a known side effect of using miniB3D, or limited to my computer/driver setup? (Windows XP MCE, 2GHz T2500 Core Duo, GeForce Go 7600, no idea about drivers or really how to find out).

I haven't had any problems running miniB3D (apart from getting to grips with the differences between Blitz3D and BlitzMax, obviously), it's just this apparently unnecessary spike in CPU usage that bothers me. I'd rather not release anything that uses more than it has to, even if it does work perfectly otherwise (because I am thoroughly obsessive. Look, it makes me happy to optimise IF structures...).

So... does anyone else get the same results? Are they to be considered normal, or is there a way around them?

Thanks for your attention.


ima747(Posted 2009) [#2]
I belive it's a blitzmax thing essentially. Blitzmax, and my extension minib3d run as fast as they possibly can to provide the smoothest motion possible. Running as fast as possible essentially uses all the CPU all the time, however modern OS's can handle the thread relatively smoothly so you can still do other things on the computer without it being locked. Additionally if you're writing games generally you're taking over the whole computer anyway so it's sort of a non issue.

There are tons of ways to deal with the CPU usage if you want to throttle it. I never used B3D so appologies for not knowing how it's delay function works so I can't give you a straight alternative. You could write your own delay command that runs PollSystem() for however long you want to wait. Here's an untested example to give you an idea
Function Delay(millisecsToWait:Int)
	Int startDelay = MilliSecs() ' Gets the time this delay started
	
	While(MilliSecs() - startDelay < millisecsToWait) ' current time - start time = how long we've been delayed
		PollSystem() ' gives the system time to do it's thing
	Wend
End Function


You could use WaitTimer().

You could potentially set the refresh rate in your call to Graphics3D() and then use Flip(1) to force screen flips only on the refreshes.

I'm sure there are many much better ways but those are a few.