Page 2 of 2
Posted: Sat Dec 01, 2007 5:18 pm
by Trond
Yes, I meant the divisor.
Obviously I meant it should only happen with constants, so you don't need to check anything at run-time. But I wasn't aware of the problem with rounding and negative numbers.
As you can see, it's much faster:
Code: Select all
tmp = 123495
t = ElapsedMilliseconds()
For i = 0 To 100000000
x = tmp/2
Next
t - ElapsedMilliseconds()
t2 = ElapsedMilliseconds()
For i = 0 To 100000000
x = tmp >> 1
Next
t2 - ElapsedMilliseconds()
MessageRequester("divide with 2",Str(-t))
MessageRequester("the other",Str(-t2))
Posted: Sat Dec 01, 2007 5:36 pm
by tinman
Edit 3: Post was full of wrong info, removed it. See below.
Posted: Sat Dec 01, 2007 5:41 pm
by thefool
Trond wrote:
Obviously I meant it should only happen with constants, so you don't need to check anything at run-time.
Good then I didn't get it all wrong

Posted: Sat Dec 01, 2007 5:50 pm
by Foz
On mine, the shift by itself is quicker (2400) than the divide (3500), but if you include the If then the total time is 4700, and if you include the If and the increment, then it pushes it to a whopping 5400.
Could really do with a quick if and increment...
Posted: Sat Dec 01, 2007 6:23 pm
by tinman
Edit2: Removed code for incorrect algorithm. See below.
Posted: Sat Dec 01, 2007 6:32 pm
by Foz

that is sloooow! 9900 for me!
Posted: Sat Dec 01, 2007 6:33 pm
by Trond
Turn off the debugger...
Posted: Sat Dec 01, 2007 6:35 pm
by Foz
Ah!
Thanks!
Posted: Sat Dec 01, 2007 7:21 pm
by tinman
OK, I think I've figured out the correct algorithm. Code below, with some example ASM.
In fact, looking at the ASM that PB currently produces it converts the long to a quad, then performs the division. So the same code works for longs and quads quite easily. I don't know how to do this shifting nicely for quads so perhaps thats another issue doing it this way.
Code: Select all
Define.l b
Define.l a
#MAX_RANGE = 100000000
;#MAX_RANGE = 10
#DIVIDE_BY = 2
#SHIFT_BY = 1
st=GetTickCount_()
For a = -#MAX_RANGE To #MAX_RANGE
b = a / #DIVIDE_BY
Next
et=GetTickCount_()
MessageRequester("Duration", Str(et-st))
st=GetTickCount_()
For a = -#MAX_RANGE To #MAX_RANGE
;b = a >> #SHIFT_BY
;If b < 0 And (a & ((1 << #SHIFT_BY)-1))
; b + 1
;EndIf
#ADJUST_MASK = (1 << #SHIFT_BY)-1
;Debug #ADJUST_MASK
MOV ebx, dword [v_a]
MOV eax, ebx
AND eax, #ADJUST_MASK
SETNZ al
AND eax, 1
ROL ebx, 1
AND eax, ebx
ROR ebx, 1
SAR ebx, #SHIFT_BY
ADD ebx, eax
MOV dword [v_b],ebx
Debug b
Next
et=GetTickCount_()
MessageRequester("Duration", Str(et-st))