i am trying to have a fast and small SQR() replacement. What do you think about following code? Are the results exact enough for you? Have i call Push and Pop too? If this routine is good enough, i will do some performence tests!
; ---- SqrtFloat Replacement !? ----
t.f = 45 ; your integer or float value for sqr
MOV eax,t
SUB eax,$3F800000
SAR eax,1
ADD eax,$3F800000
MOV t,eax
MessageRequester("ASM Testing", "Result: "+StrF(t), 0)
End
Psychophanta wrote:But Sqr() PB function is fast enough
In time critical situations, nothing is fast enough
Ralfs suggestion was just a rough estimation of sqrt, which I bet will be faster
than a "real sqrt" while still having a sufficient result in cases where speed is
more important than accuracy.
Good programmers don't comment their code. It was hard to write, should be hard to read.
Traumatic, you're wrong.
Current Intel FPU is as faster or more than ALU. Which means that you will get more speed at more accuracy.
Simply compare speeds with Sqr() PB function against another ASM function made using ALU only. But before of it: if you want to bet, i am disposed (i say Sqr() will win in: accuracy and speed)
thanks to Psychophanta and traumatic for the discussion! also as i understand it right, my routine is nowadays more or less useless because psychophanta´s methode is fast enough on today cpus?
Procedure.f Sqrt(N.f)
!mov eax, [p.v_N]
!sub eax, $3F800000
!shr eax, 1
!add eax, $3F800000
!mov [esp-4], eax
!fld dword [esp-4]
CompilerIf #PB_Compiler_Debugger
ProcedureReturn
CompilerElse
!ret 4
CompilerEndIf
EndProcedure
#Tries = 50000000
z.f
time = GetTickCount_()
For I = 0 To #Tries
z = I
Sqrt(z)
Next
MessageRequester("", Str(GetTickCount_()-time))
z.f
time = GetTickCount_()
For I = 0 To #Tries
z = I
Sqr(z)
Next
MessageRequester("", Str(GetTickCount_()-time))
if you take an average of the quick result and the number you are trying to find the root of divided by the quick result then you improve the accuracy by quite a large margin.
OpenConsole()
i=100000000; any less than 1000000 and it becomes slower than SQR()
r=ElapsedMilliseconds()
For l=1 To i
g.f=Sqr(l)
Next
r=ElapsedMilliseconds()-r
PrintN("Actual SQR() = "+StrF(g)+" in "+Str(r))
r=ElapsedMilliseconds()
For l=1 To i
g.f = l
MOV eax,g
SUB eax,$3F800000
SAR eax,1
ADD eax,$3F800000
MOV g,eax
Next
r=ElapsedMilliseconds()-r
PrintN("Approx SQR() = "+StrF(g)+" in "+Str(r))
r=ElapsedMilliseconds()
For l=1 To i
g.f = l
MOV eax,g
SUB eax,$3F800000
SAR eax,1
ADD eax,$3F800000
MOV g,eax
n.f=(g+l/g)/2
Next
r=ElapsedMilliseconds()-r
PrintN("Averaged SQR() = "+StrF(n)+" in "+Str(r))
Input()