Page 1 of 2
Strange optimization issue
Posted: Tue Apr 29, 2008 11:06 pm
by Derek
While trying to find a few ways to speed up my program I thought I'd time a few things. In the program below why does it take longer to do the straight forward a=testy etc than the a=testy-1 etc, surely the maths would slow it down.
I was going to put the calculation outside out the loop in my program as it scans a whole picture and could be called millions of times but now I'm not so sure.
Code: Select all
DisableDebugger
OpenConsole()
testy=100
For m=1 To 10
t=ElapsedMilliseconds()
For n=1 To 50000000
a=testy-1
b=testy-1
c=testy-1
d=testy-1
Next
t=ElapsedMilliseconds()-t
PrintN(Str(t))
Next
PrintN("")
For m=1 To 10
t=ElapsedMilliseconds()
For n=1 To 50000000
a=testy
b=testy
c=testy
d=testy
Next
t=ElapsedMilliseconds()-t
PrintN(Str(t))
Next
PrintN("")
Input()
I know an average size photo is probably about 6-8 million pixels but when you add up the four loops used in my program along with a few dozen IF's in each then every millisecond is going to count.
Posted: Wed Apr 30, 2008 12:47 am
by Joakim Christiansen
WTF

Posted: Wed Apr 30, 2008 2:52 am
by Sparkie
I'm no ASM expert but maybe it's a PUSH/POP vs MOV issue?
Partial ASM output from the
variable=testy-1 loop...
Code: Select all
CALL _PB_ElapsedMilliseconds@0
MOV dword [v_t],eax
MOV dword [v_n],1
_For3:
MOV eax,50000000
CMP eax,dword [v_n]
JL _Next4
MOV ebx,dword [v_testy]
DEC ebx
MOV dword [v_a],ebx
MOV ebx,dword [v_testy]
DEC ebx
MOV dword [v_b],ebx
MOV ebx,dword [v_testy]
DEC ebx
MOV dword [v_c],ebx
MOV ebx,dword [v_testy]
DEC ebx
MOV dword [v_d],ebx
_NextContinue4:
INC dword [v_n]
JMP _For3
_Next4:
CALL _PB_ElapsedMilliseconds@0
Partial ASM output from the
variable=testy loop...
Code: Select all
CALL _PB_ElapsedMilliseconds@0
MOV dword [v_t],eax
MOV dword [v_n],1
_For3:
MOV eax,50000000
CMP eax,dword [v_n]
JL _Next4
PUSH dword [v_testy]
POP dword [v_a]
PUSH dword [v_testy]
POP dword [v_b]
PUSH dword [v_testy]
POP dword [v_c]
PUSH dword [v_testy]
POP dword [v_d]
_NextContinue4:
INC dword [v_n]
JMP _For3
_Next4:
CALL _PB_ElapsedMilliseconds@0
Posted: Wed Apr 30, 2008 9:22 am
by blueznl
Weird indeed!
is twice as fast as
Time for some optimization I guess

Posted: Wed Apr 30, 2008 9:42 am
by DoubleDutch
Now that is crazy. Do we do the optimisation by putting -0 all over the place or do you reckon it will be in the compiler.
Posted: Wed Apr 30, 2008 9:49 am
by Foz
Who wants to place a bet that it'll be fixed for Beta 5

Posted: Wed Apr 30, 2008 10:31 am
by tinman
Posted: Wed Apr 30, 2008 2:04 pm
by Derek
You know what, I thought I had seen this somewhere before but didn't look that far back.
Still, you'd of thought it might of been
fixed by now.

Posted: Wed Apr 30, 2008 3:25 pm
by Joakim Christiansen
DoubleDutch wrote:Now that is crazy. Do we do the optimisation by putting -0 all over the place or do you reckon it will be in the compiler.
I sure hope they optimize the compiler, would be nice if the team comment on this.
Posted: Wed Apr 30, 2008 4:04 pm
by Trond
Just a note: This happens only outside procedures. Inside procedures even a direct assignment uses mov. So just structure your code and it will be fast.

Posted: Wed Apr 30, 2008 4:30 pm
by Derek
Code: Select all
DisableDebugger
Procedure test()
OpenConsole()
testy=100
For m=1 To 10
t=ElapsedMilliseconds()
For n=1 To 50000000
a=testy-1
b=testy-1
c=testy-1
d=testy-1
Next
t=ElapsedMilliseconds()-t
PrintN(Str(t))
Next
PrintN("")
For m=1 To 10
t=ElapsedMilliseconds()
For n=1 To 50000000
a=testy
b=testy
c=testy
d=testy
Next
t=ElapsedMilliseconds()-t
PrintN(Str(t))
Next
PrintN("")
EndProcedure
test()
testy=100
For m=1 To 10
t=ElapsedMilliseconds()
For n=1 To 50000000
a=testy-1
b=testy-1
c=testy-1
d=testy-1
Next
t=ElapsedMilliseconds()-t
PrintN(Str(t))
Next
PrintN("")
For m=1 To 10
t=ElapsedMilliseconds()
For n=1 To 50000000
a=testy
b=testy
c=testy
d=testy
Next
t=ElapsedMilliseconds()-t
PrintN(Str(t))
Next
PrintN("")
Input()
On mine it is even worse inside procedures so it looks like structured programming is out.

Posted: Wed Apr 30, 2008 5:43 pm
by Trond
HOW MANY *^!"#¤%&/()=?=)(/&%¤# TIMES DO I HAVE TO SAY THIS? TURN OFF THE DEBUGGER WHEN SPEED TESTING!
Posted: Wed Apr 30, 2008 5:56 pm
by Derek
LOOK AT THE *^!"#¤%&/()=?=)(/&%¤# FIRST LINE OF CODE.
But even if I turn off the debugger first, which does in fact make a difference (

to Trond) then my fastest result is from the -1 code outside of the procedure and my slowest result is from the straight a=testy code outside the procedure, inside the procedure both results are roughly equal.
Posted: Wed Apr 30, 2008 7:07 pm
by Trond
Local variables will probably be a bit slower since they are accessed relative to the stack instead of directly. However, the fastest one here (with the debugger truly OFF), is the second one inside the procedure. It beats the -1 outside by only a small margin, which is turned around when I write to file instead of to the console, so it's probably a caching/pipelining/alignment coincidence.
Posted: Wed Apr 30, 2008 7:24 pm
by Trond
The DisableDebugger part really should work in my opinion. (But the fact is, that it doesn't completely work.) Maybe it's a bug?