code execution question

BlitzMax Forums/BlitzMax Programming/code execution question

Cruis.In(Posted 2013) [#1]
Hey fellas got some questions on delayed code execution.

Firstly is using millisecs() alot taxing? For delayed execution?

if millisecs - fixedtimevariable > time you want to wait
do code

or is it better to make your own timer and only ever called millisecs once which is at the start of the program to make your own timer

global start_time = millisecs() 'time when program started

'loop

currentTime = millisecs - start_time

(divide by 1000 if you want to get one digit)

then instead of using millisecs for events it would be

if current_time - fixedtime variable > time to wait
do code

fixed time variable would receive its value when you want it to and be based on current time.

If a user starts his car, then carStarted = currenTime.

But that only makes sense to do if using millisecs() all the time is taxing in some way right?

Secondly...

If you are going to have to wait for a period of time for code to execute this code MUST be being executed in the loop correct? No other way around it?

So you have a

Function

if millisecs - timevariable > Xtime
do code

end function

If you want it to be based on a timer, the only way to know if that timer has reached is for it to be in the loop. Otherwise even if you call that function, if its outside the loop, that code inside there doesn't get a chance to count.

So my question is, is there anything bad about having that function in the loop always, just waiting until its time condition has been met?


ImaginaryHuman(Posted 2013) [#2]
If you just do a loop of Millisecs() it will give 100% (or much as possible) cpu time to executing that loop, millions/billions of times per second. It will be a total hog. If possible try using timers so that maybe you check the time only once in a while. Alternatively throw in a `Delay 1` in between millisecs calls to give 1ms to the operating system, or more, if you don't have other work to do.


Cruis.In(Posted 2013) [#3]
so if I wanted to time a space ship ignition

LaunchButton // a gui button

if LaunchButton.IsClicked

launchTime = Current_time

end if


Now the spaceship type has an updateall function

for s:spaceship

s.update
s.draw
s.launch

//

that updateall is in the main loop.

spaceship.updateall

now the Launch function is

function launch

if current_time - launch time > 5
take_off
end if

end function

Just to describe what I mean better. And so now you are saying, while Launch() is counting down its a hog. What if I used:

if current_time - launchtime < 5 return


the code isn't counting until the you click take off. Still bad?


Jesse(Posted 2013) [#4]
That looks good.

if you need to call the Millisecs funciton many times per flip, it's best to call it only once and store it into a global variable. it will be quite a bit faster. Although it is recommended not to use global variables, there is a reason why they exist, just don't go crazy with them.


Cruis.In(Posted 2013) [#5]
Yep ok thanks. I actually don't call it more than once now. It's called once for current time.

i havent noticed any hogs, but was very curious about the 'tax', since i been trying to clean things up with the 'things to avoid' rules.

like no more graphicsheight() calls.


matibee(Posted 2013) [#6]
Why no more calls to graphicsheight() ??

If you open up the source in brl.mod\graphics.mod\graphics.bmx, you'll find the function does nothing more than return a global variable value :

Function GraphicsHeight()
	Return _gHeight
End Function


The function call overhead is likely to be optimised out by the compiler anyway.

It's a good thing to be wary of calling functions too often if you don't understand their overhead, but the good thing about blitxmax is that most of the function code is there to be explored :)


Cruis.In(Posted 2013) [#7]
i had heard it was 'slow'...


Brucey(Posted 2013) [#8]
The function call overhead is likely to be optimised out by the compiler anyway.

I wouldn't like to assume such things.


zzz(Posted 2013) [#9]
What Brucey said, the blitzmax compiler tend to just to a flat translation to assembly code. Put a quick example below. Setting a variable to getval() will be about ten times slower then assigning the value directly. Not that it really matters.

Function getval:Int()
	Return 10
End Function


_bb_getval:
	push	ebp
	mov	ebp,esp
	mov	eax,10
	jmp	_5
_5:
	mov	esp,ebp
	pop	ebp
	ret



col(Posted 2013) [#10]
I'm surprised the assembly compiler doesnt optimise out the unnecessary jmp calls at the end of the functions as shown here ( no doubt generated by the blitz compilers code block analysis ). They are kept in the final exe.

	jmp	_5
_5:
	mov	esp,ebp


'Local's tend to get put directly into the cpu registers, and 'Global's get assigned to a memory address which, when needed, gets copied into a register. Function calls can be slower because of setting up a stack frame as shown in zzz example.

But also as noted - these are micro optimisations that you shouldn't really need to worry about. Saying that though, this is a good example of why calling a function from inside a heavy loop could be optimised by 'inlining' whats in the function to be inside the loop itself, thereby getting rid of the stack frame code and potentially using Locals and/or direct variable access for faster code. Common sense should help choose between writing the source code for an end result of speed or readability.


zzz(Posted 2013) [#11]
yeah fasm is supposed to be like that, hence the f(lat) in there. im fairly certain the guy that wrote it was quite a bit into os dev when he started working on fasm, so it makes sense.


Cruis.In(Posted 2013) [#12]
ok so graphicswidth() fine, millisecs bad :)


zzz(Posted 2013) [#13]
It's "not" fine either, all functions suffer from this. Just do what Jesse said, if you call millisecs() or graphicswidth() a handful of times per frame in a game or something, it wont be noticeable at all. However if you, say, have a few thousand particles that get updates each frame, and you call graphicswidth() for each particle when updating, it will make a difference.