floating-point Pow2() functions for Float and Double, a bit faster than PB's Pow(n,2) (not a fair competition though as PB's Pow() is general-purpose supporting both integer+float and variable exponent)
CompilerIf #PB_Compiler_Debugger
CompilerError("Error - Turn off debugger for timings")
CompilerEndIf
Procedure.f Powf2(value.f)
! fld dword [p.v_value] ;load 32bit Float
! fmul st, st ;pow2 = value * value
! fstp dword [p.v_value] ;store
ProcedureReturn value
EndProcedure
Procedure.d Powd2(value.d)
! fld qword [p.v_value] ;load 64bit Double
! fmul st, st ;pow2 = value * value
! fstp qword [p.v_value] ;store
ProcedureReturn value
EndProcedure
Define result.f, ftest.f = 7
Time1 = ElapsedMilliseconds()
For i = 1 To 9000000
result = Pow(ftest, 2)
Next i
Time2 = ElapsedMilliseconds()
MessageRequester("Purebasic Pow()", Str(Time2-Time1))
Time1 = ElapsedMilliseconds()
For i = 1 To 9000000
result = Powf2(ftest)
Next i
Time2 = ElapsedMilliseconds()
MessageRequester("asm Powf2()", Str(Time2-Time1))
Last edited by Keya on Fri Mar 04, 2016 9:52 pm, edited 1 time in total.
Procedure.f Powf2(value.f)
! fld dword [p.v_value] ;load 32bit Float
! fmul st, st ;pow2 = value * value
! fstp dword [p.v_value] ;store
ProcedureReturn value
EndProcedure
Procedure.d Powd2(value.d)
! fld qword [p.v_value] ;load 64bit Double
! fmul st, st ;pow2 = value * value
! fstp qword [p.v_value] ;store
ProcedureReturn value
EndProcedure
Macro Powr2(value)
(value * Value)
EndMacro
Define result.f, ftest.f = 7
Time1 = ElapsedMilliseconds()
For i = 1 To 9000000
result = Pow(ftest, 2)
Next i
Time2 = ElapsedMilliseconds()
MessageRequester("Purebasic Pow()", Str(Time2-Time1))
Time1 = ElapsedMilliseconds()
For i = 1 To 9000000
result = Powf2(ftest)
Next i
Time2 = ElapsedMilliseconds()
MessageRequester("asm Powf2()", Str(Time2-Time1))
Time1 = ElapsedMilliseconds()
For i = 1 To 9000000
result = Powr2(ftest)
Next i
Time2 = ElapsedMilliseconds()
MessageRequester("asm Powr2()", Str(Time2-Time1))
On my computer I got 96 ms, 77 ms and 31 ms
Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
Procedure.f Powf2(value.f)
! fld dword [p.v_value] ;load 32bit Float
! fmul st, st ;pow2 = value * value
! fstp dword [p.v_value] ;store
ProcedureReturn value
EndProcedure
bufa = AllocateMemory(9000000)
bufb = AllocateMemory(9000000)
*p1.Ascii = bufa
*p2.Ascii = bufb
Time1 = ElapsedMilliseconds()
For i = 1 To 9000000
;ft = Sqr(Abs(Pow(*p1\a,2) - Pow(*p2\a,2))) ;=257, 248, 249
;ft = Sqr(Abs(Powf2(*p1\a) - Powf2(*p2\a))) ;=48, 50, 48
ft = Sqr(Abs(*p1\a * *p1\a) - (*p2\a * *p2\a)) ;=34, 41, 33
*p1+1: *p2+1
Next i
Time2 = ElapsedMilliseconds()
MessageRequester("Time", Str(Time2-Time1))
but that leaves me perplexed as to why it's performing differently in my other code! completely different timings from what should be identical code. Well... at the end of the day i'll be saving a lot of time (have to call this a lot), that's the main thing lol
ahhh yes! good catch thankyou caffeine levels not good here for debugging
the speed of the procedure is actually really good so far, Pow() seemingly the only bottleneck. I wasnt sure how Sqr() would go but it seems fast, and likewise no hiccups from Abs()
Keya wrote:I wasnt sure how Sqr() would go but it seems fast, and likewise no hiccups from Abs()
Pow() requires multiple instructions, Sqr() only one (fsqrt). How fast that fsqrt instruction is, depends a lot on the cpu architecture but on a modern Intel cpu it's quite fast.