|
Post by Roger Cabo on Dec 17, 2023 23:04:42 GMT 1
Didn't find any info about SinQ(), CosQ() in the help file. Not sure what it takes.. Msgbox SinQ(1) * Deg(1) & " = " & Sin(1)
Also .net has a Math.sincos(x).. does anyone know what the code is behind? It creates sin(x) and calculate quickly cox(x) of it. takes normaly 200ticks (cos(x) and sin(x))
|
|
|
Post by (X) on Dec 18, 2023 0:20:31 GMT 1
Pretty sure SinQ takes degrees instead of radians, so, SinQ(45) = 0.707106781186547 etc...
|
|
webu
Full Member
Posts: 149
|
Post by webu on Dec 18, 2023 0:48:00 GMT 1
Pretty sure SinQ takes degrees instead of radians, so, SinQ(45) = 0.707106781186547 etc... and SinQ() is quicker than the 'normal' sin(). Just try it, because i havn't.
|
|
|
Post by (X) on Dec 18, 2023 4:19:51 GMT 1
From what I can tell, the performance of SinQ and Sin are almost identical... Compiled version is about 10% faster.
$Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx OpenW 1
Dim s# Dim c% Dim a# = 45 Dim t# = Timer For c = 1 To 1e7 s = SinQ(a) Next c Print "dt", Timer - t
a = Rad(45) t = Timer For c = 1 To 1e7 s = Sin(a) Next c Print "dt", Timer - t
Do : Sleep : Until Me Is Nothing
|
|
|
Post by Roger Cabo on Dec 18, 2023 15:27:01 GMT 1
Thank you... Have a look at this isn't it strange? Result! dt 0.412964099999946 31457270 dt 0.748223699999888 31457270 $Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx
Dim s# Dim c% Dim a# = 45 Dim t# = Timer
$StepOff // Simulate exe speed
a = Rad(45) t = Timer For c = 1 To $2fffff s = Sin(a + 1.7) s = Cos(a + 3.4) s = Sin(a + 4.5) s = Cos(a + 2.3) s = Sin(a + 1.1) s = Cos(a + 4.9) s = Sin(a + 6.6) s = Cos(a + 9.4) s = Sin(a + 3.7) s = Cos(a + 5.8) Next c t = Timer - t
Debug.Print "dt", t & " " & $2fffff * 10
t = Timer For c = 1 To $2fffff s = Sin(a + 1.1) s = Cos(a + 1.1) s = Sin(a + 1.1) s = Cos(a + 1.1) s = Sin(a + 1.1) s = Cos(a + 1.1) s = Sin(a + 1.1) s = Cos(a + 1.1) s = Sin(a + 1.1) s = Cos(a + 1.1) Next c t = Timer - t Debug.Print "dt", t & " " & $2fffff * 10
Debug.Show Stop
Perhaps Frank Ostrovski, saved the input value and result from Sin/Cos/etc.. And if the input it's the same like the previous result, then he collects the result from the memory. On nowadays machines the sin/cos fp operations require only some cycles on fpu/cpu.
|
|
|
Post by (X) on Dec 18, 2023 16:47:15 GMT 1
I think there may be more variance depending on which order these loops are performed than the types of variables used. As I try to reorder the fastest loop to the bottom, the 'delta t' changes significantly and the 'fastest' before is no longer the fastest after. In any case, there is no clear 'winner' as far as I can tell.
$Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx OpenW 1 Win_1.FontSize = 14
Dim S# Dim pS As Pointer Double Pointer pS = *S
Dim A# = 45 Dim pA As Pointer Double Pointer pA = *A
Dim C% Dim pC As Pointer Long Pointer pC = *C ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
t# = Timer For C = 1 To 1000000 pA = t S = Sin(pA) Next C Print "dt", Timer - t
Dim t# = Timer For C = 1 To 1000000 A = t S = SinQ(A) Next C Print "dt", Timer - t
t# = Timer For pC = 1 To 1000000 pA = t pS = Sin(pA) Next pC Print "dt", Timer - t
t# = Timer For C = 1 To 1000000 A# = t# + 0.1 pS = Sin(A#) Next C Print "dt", Timer - t
t# = Timer For C = 1 To 1000000 A = t S = Sin(A) Next C Print "dt", Timer - t
t# = Timer For C = 1 To 1000000 pA = t pS = Sin(pA) Next C Print "dt", Timer - t
Print "Done." Do : Sleep : Until Me Is Nothing
|
|
webu
Full Member
Posts: 149
|
Post by webu on Dec 18, 2023 18:53:14 GMT 1
I think, my info, that the Qs are quicker, is about gfa for Atari. I wrote a CAD-Programm in the last century in GFA and i remember, that the speed-results of the Q-Variations based on interpolation of table values. From the german manual:
SIN(x) SINQ(grad) SIN() berechnet den Sinus von 'x', das als Bogenmaß interpretiert wird. Die Funktion SINQ() erwartet dagegen einen Wert im Gradmaß, außerdem berechnet sie den Funktionswert nicht genau, sondern ermittelt ihn anhand einer Tabelle und Interpolation. Daher ist SINQ() ca. 10 mal schneller als SIN(), aber auch ungenauer. Siehe auch: COS Gruppe: Mathematische Funktionen
|
|
webu
Full Member
Posts: 149
|
Post by webu on Dec 18, 2023 19:02:31 GMT 1
In the first versions of the 68000 processor there were no special native FPU-functions. FPU-operations were realized in normal machine-code-instructions. In these times we all think in 2-byte integer, maybe in 4-byte integer, but not in float! Hard times these times! :-)
|
|
|
Post by wbtcpip on Dec 18, 2023 19:16:56 GMT 1
In the first versions of the 68000 processor there were no special native FPU-functions. FPU-operations were realized in normal machine-code-instructions. In these times we all think in 2-byte integer, maybe in 4-byte integer, but not in float! Hard times these times! :-) oh yes i remember when i was usign gfa basic on amiga in 1990
|
|
|
Post by dragonjim on Dec 18, 2023 23:05:37 GMT 1
From the English help file: Annoyingly I left them out of the index when I rewrote the page - they will be in the next version.
|
|
|
Post by dragonjim on Dec 19, 2023 0:30:10 GMT 1
As for the sincos function, it would seem that the speed advantage comes from using the Assembly instruction fsincos which was present in 80387(?) coprocessors and later. GFA doesn't seem to use this instruction but stays with the basic fmul, fdiv, etc. instructions, possibly to stay compatible with older machines of the day.
|
|
|
Post by Roger Cabo on Jan 3, 2024 22:34:56 GMT 1
Try this...
Dim v# = 1.0 Dim sy# = 0 Dim cy# = 0 Dim i%
Dim t1#
t1# = Timer For i% = 0 To 1000000 . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# Next i% MsgBox Timer - t1#
t1# = Timer For i% = 0 To 1000000 sy# = Sin(v#) cy# = Cos(v#) Next i% MsgBox Timer - t1#
|
|
|
Post by (X) on Jan 4, 2024 1:45:06 GMT 1
Well color me impressed!
This trick shows up to 40% impovement when running the compiled version!
That is not nothing!
Well done!
$Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx OpenW 1 FontSize = 16 Dim v# = 1.0 Dim sy# = 0 Dim cy# = 0 Dim i%
Dim t1#, dt1#, dt2# Print "Timer:"; Timer t1# = Timer For i% = 0 To 1000000 . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# Next i% Print "cy, sy:"; cy, sy dt1 = Timer - t1# Print "dt1:"; dt1
t1# = Timer For i% = 0 To 1000000 sy# = Sin(v#) cy# = Cos(v#) Next i% Print "cy, sy:"; cy, sy
dt2 = Timer - t1# Print "dt2:"; dt2
Print "% faster:", Round(100 * (Max(dt2, dt1) - Min(dt1, dt2)) / Max(dt1, dt2)); "%"
Do : Sleep : Until Me Is Nothing
|
|
|
Post by scalion on Jan 4, 2024 12:33:18 GMT 1
I put this code in naked proc...
Proc PT1() Naked . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# EndProc
Proc PT2() Naked sy# = Sin(v#) cy# = Cos(v#) EndProc
Take a look on the disassembled : With asm :
04D40E50: DD 05 90 CC FB 05 fld qpt [0x05FBCC90] 04D40E56: D9 FB fsincos 04D40E58: DD 1D A0 CC FB 05 fstp qpt [0x05FBCCA0] 04D40E5E: DD 1D 98 CC FB 05 fstp qpt [0x05FBCC98]
With GFA :
04D41150: DD 05 90 CC FB 05 fld qpt [0x05FBCC90] 04D41156: FF 15 E0 1A 4D 00 scall SIN ; Ocx: $18059B80 04D4115C: DD 1D 98 CC FB 05 fstp qpt [0x05FBCC98] 04D41162: DD 05 90 CC FB 05 fld qpt [0x05FBCC90] 04D41168: FF 15 E4 1A 4D 00 scall COS ; Ocx: $18059BA0 04D4116E: DD 1D A0 CC FB 05 fstp qpt [0x05FBCCA0]
|
|
|
Post by (X) on Jan 4, 2024 16:06:06 GMT 1
It seems there is a basic difference between fsincos (2 operations combined into one statement) and doing sin and cos separately. I imagine Sjouke could implement SinCos as an optional way to get the Sin and Cos of an angle. Actually we might create our own function that calls fsincos assembly code and see if that is faster.
I asked BING for an appraisal of the GFA code... With GFA : 04D41150: DD 05 90 CC FB 05 fld qpt [0x05FBCC90] 04D41156: FF 15 E0 1A 4D 00 scall SIN ; Ocx: $18059B80 04D4115C: DD 1D 98 CC FB 05 fstp qpt [0x05FBCC98] 04D41162: DD 05 90 CC FB 05 fld qpt [0x05FBCC90] 04D41168: FF 15 E4 1A 4D 00 scall COS ; Ocx: $18059BA0 04D4116E: DD 1D A0 CC FB 05 fstp qpt [0x05FBCCA0] It appears you've posted some assembly language code. Here's a brief explanation of the instructions: - `fld qpt [0x05FBCC90]`:
This instruction loads a floating-point value from the memory address `0x05FBCC90` onto the floating-point stack.
- `scall SIN`: This is a system call to the `SIN` function, which typically calculates the sine of a value.
- `fstp qpt [0x05FBCC98]`:
This instruction stores the top value from the floating-point stack to the memory address `0x05FBCC98` and then pops that value off the stack.
- `scall COS`: This is a system call to the `COS` function, which typically calculates the cosine of a value. The ; Ocx: $18059BA0 appears to be a comment in the assembly code you provided. In assembly language, anything following a semicolon (;) is considered a comment and is ignored by the assembler during the assembly process.
|
|
|
Post by (X) on Jan 4, 2024 16:31:16 GMT 1
Here is an updated comparison. The inline assembly code seems to be significantly faster. 17% vs 7% on my machine. By putting the assembly code in a SinCos() procedure we still save some time.
$Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx FullW 1 AutoRedraw = 1 FontSize = 16 Global v# = 1.0 Dim sy# = 0 Dim cy# = 0 Dim i%
Dim t1#, dt1#, dt2#, dt3#, dt4# Print "Timer:"; Timer
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 1 ' t1# = Timer For i% = 0 To 1000000 v# = Timer . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# Next i%
Print "cy, sy:"; cy, sy, dt1 = Timer - t1# Print "dt1:"; dt1
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 2 ' t1# = Timer For i% = 0 To 1000000 v# = Timer sy# = Sin(v#) cy# = Cos(v#) Next i%
Print "cy, sy:"; cy, sy, dt2 = Timer - t1# Print "dt2:"; dt2
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 3 ' t1# = Timer For i% = 0 To 1000000 v# = Timer SinCos(v#, sy#, cy#) Next i%
Print "cy, sy:"; cy, sy, dt3 = Timer - t1# Print "dt3:"; dt3
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 4 ' t1# = Timer For i% = 0 To 1000000 v# = Timer ~F_SinCos(v#, sy#, cy#) Next i%
Print "cy, sy:"; cy, sy, dt4 = Timer - t1# Print "dt4:"; dt4
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Comparison Report ' Print Dim mx# = Max(dt1, dt2, dt3, dt4) Print "Test 1:", Round(100 * (mx - dt1) / mx); "% faster" Print "Test 2:", Round(100 * (mx - dt2) / mx); "% faster" Print "Test 3:", Round(100 * (mx - dt3) / mx); "% faster" Print "Test 4:", Round(100 * (mx - dt4) / mx); "% faster"
Do : Sleep : Until Me Is Nothing
Proc SinCos(a#, ByRef s#, ByRef c#) Naked . fld qpt [a#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [c#] ; Speichert das Ergebnis in cy# . fstp qpt [s#] ; Speichert das Ergebnis in sy# EndProc
Function F_SinCos(a#, ByRef s#, ByRef c#) As Bool Naked . fld qpt [a#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [c#] ; Speichert das Ergebnis in cy# . fstp qpt [s#] ; Speichert das Ergebnis in sy# EndFunc
|
|
|
Post by Roger Cabo on Jan 4, 2024 17:44:29 GMT 1
If you put the API call v# = Timer into the counter, so your results are not really comparable.
v# = Timer takes the same time as sy# = Sin(v#) cy# = Cos(v#)
and for sure you taken the For Loop into account as well. I think the following test is more fair.
It runs also 1Mio times but the for loops takes only 10% collateral -----------------------
Timer: 1714.8372491 Test 1 cy, sy: 0.211619957584603 -0.977352031538223 v#: 1000000 dt1: 0.0188899999999664 Test 2 cy, sy: 0.211619957584603 -0.977352031538223 v#: 1000000 dt2: 0.0485501000000187 % faster: 61%
-----------------------
$Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx
Dim v# = 0.0 Dim sy# = 0 Dim cy# = 0 Dim i%
Dim t1#, dt1#, dt2# Debug.Show Debug "Timer:"; Timer t1# = Timer
$StepOff
For i% = 0 To 100000 - 1 . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# v#++ Next i% dt1 = Timer - t1#
Debug "Test 1" Debug "cy, sy:"; cy, sy; " v#: "; v# Debug "dt1:"; dt1
v# = 0
t1# = Timer For i% = 0 To 100000 - 1 sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ sy# = Sin(v#) cy# = Cos(v#) v#++ Next i% dt2 = Timer - t1#
Debug "Test 2" Debug "cy, sy:"; cy, sy; " v#: "; v# Debug "dt2:"; dt2 Debug "% faster:", Round(100 * (Max(dt2, dt1) - Min(dt1, dt2)) / Max(dt1, dt2)); "%"
Debug.Show Debug.Refresh
Stop
I need fsincos to calculate Euler to quaternion.. And the newer SIM floating calculation is a lot faster then the old FPU stuff.. but we have no other chance in gb32.
Function I_EulerToQuat(ByRef euler As Vector3) As Quaternion Dim e As Vector3 e = euler e.x *= 0.00872664625997165 e.y *= 0.00872664625997165 e.z *= 0.00872664625997165 // later °. fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack °. fsincos ; Berechnet den Kosinus von v# erneut °. fstp qpt [cy#] ; Speichert das Ergebnis in cy# °. fstp qpt [sy#] ; Speichert das Ergebnis in sy#
Dim cy# = Cos(e.z) Dim sy# = Sin(e.z) Dim cp# = Cos(e.y) Dim sp# = Sin(e.y) Dim cr# = Cos(e.x) Dim sr# = Sin(e.x) // Berechne Quaternion-Komponenten (vertauschte x und y) Dim q As Quaternion q.y = (cr * sp * cy) - (sr * cp * sy) q.x = (sr * cp * cy) + (cr * sp * sy) q.z = (cr * cp * sy) - (sr * sp * cy) q.w = (cr * cp * cy) + (sr * sp * sy) Return q End Function
And if you like to use the original code of the FPU.. you can use this in GB32. But it's too slow! You can reduce the N-Terme 1 to 10, to speed up things, but resulting in lower precision.
Proc FSinCos(x As Double, ByRef sinResult As Double, ByRef cosResult As Double) Naked Dim sumSin As Double Dim sumCos As Double Dim term As Double Dim i As Integer
sumSin = x ' Initialwert für Sinus sumCos = 1 ' Initialwert für Kosinus term = x ' Gemeinsamer Term
// Berechne Sinus und Kosinus als Summe der ersten n Terme der McLaurin-Reihe For i = 1 To 10 ' Anzahl der Terme für die Näherung term = -term * x * x / ((2 * i - 1) * (2 * i)) If i Mod 2 = 0 Then sumCos = sumCos + term Else sumSin = sumSin + term * x / (2 * i + 1) End If Next i
sinResult = sumSin cosResult = sumCos End Sub
|
|
|
Post by (X) on Jan 4, 2024 18:36:24 GMT 1
I am not sure why but Test #7 is sometimes the fastest... It uses a User Defined Type. $Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx FullW 1 AutoRedraw = 1 FontSize = 16 Global v# = 1.0 Global sy# = 0 Global cy# = 0 Dim i%
Dim t1#, dt1#, dt2#, dt3#, dt4#, dt5#, dt6#, dt7#
Type T_SinCos -Double a -Double cos -Double sin EndType
Global sc As T_SinCos
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 1 ' DoEvents t1# = Timer For i% = 0 To 1000000 v# = Timer . fld qpt [v#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [cy#] ; Speichert das Ergebnis in cy# . fstp qpt [sy#] ; Speichert das Ergebnis in sy# Next i% dt1 = Timer - t1#
Print "cy, sy:"; cy, sy, Print "dt1:"; dt1
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 2 ' DoEvents t1# = Timer For i% = 0 To 1000000 v# = Timer cy# = Cos(v#) sy# = Sin(v#) Next i% dt2 = Timer - t1#
Print "cy, sy:"; cy, sy, Print "dt2:"; dt2
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 3 ' DoEvents t1# = Timer For i% = 0 To 1000000 v# = Timer P_SinCos(v#, sy#, cy#) Next i% dt3 = Timer - t1#
Print "cy, sy:"; cy, sy, Print "dt3:"; dt3
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 4 ' DoEvents t1# = Timer For i% = 0 To 1000000 v# = Timer ~F_SinCos(v#, sy#, cy#) Next i% dt4 = Timer - t1#
Print "cy, sy:"; cy, sy, Print "dt4:"; dt4
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 5 ' °04D41150: DD 05 90 CC FB 05 fld qpt [0x05FBCC90] °04D41156: FF 15 E0 1A 4D 00 scall SIN ; Ocx: $18059B80 °04D4115C: DD 1D 98 CC FB 05 fstp qpt [0x05FBCC98] °04D41162: DD 05 90 CC FB 05 fld qpt [0x05FBCC90] °04D41168: FF 15 E4 1A 4D 00 scall COS ; Ocx: $18059BA0 °04D4116E: DD 1D A0 CC FB 05 fstp qpt [0x05FBCCA0]
DoEvents t1# = Timer For i% = 0 To 1000000 v# = Timer . fld qpt [v#] . scall SIN . fstp qpt [sy#] . fld qpt [v#] . scall COS . fstp qpt [cy#] Next i% dt5 = Timer - t1#
Print "cy, sy:"; cy, sy, Print "dt5:"; dt5
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 6 ' t1# = Timer For i% = 0 To 1000000 sc.a = Timer P_SinCos2 Next i% dt6 = Timer - t1#
Print "cy, sy:"; sc.cos, sc.sin, Print "dt6:"; dt6
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 7 ' t1# = Timer For i% = 0 To 1000000 sc.a = Timer . fld qpt [sc.a] . fsincos . fstp qpt [sc.cos] . fstp qpt [sc.sin] Next i% dt7 = Timer - t1#
Print "cy, sy:"; sc.cos, sc.sin, Print "dt7:"; dt7
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Comparison Report ' Print Dim mx# = Max(dt1, dt2, dt3, dt4, dt5, dt6, dt7) Print "Test 1:", Round(100 * (mx - dt1) / mx); "% faster than slowest." Print "Test 2:", Round(100 * (mx - dt2) / mx); "% faster than slowest." Print "Test 3:", Round(100 * (mx - dt3) / mx); "% faster than slowest." Print "Test 4:", Round(100 * (mx - dt4) / mx); "% faster than slowest." Print "Test 5:", Round(100 * (mx - dt5) / mx); "% faster than slowest." Print "Test 6:", Round(100 * (mx - dt6) / mx); "% faster than slowest." Print "Test 7:", Round(100 * (mx - dt7) / mx); "% faster than slowest."
Do : Sleep : Until Me Is Nothing
Proc P_SinCos(a As Double, ByRef s#, ByRef c#) Naked . fld qpt [a] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [c#] ; Speichert das Ergebnis in cy# . fstp qpt [s#] ; Speichert das Ergebnis in sy# EndProc
Function F_SinCos(a#, ByRef s#, ByRef c#) As Bool Naked . fld qpt [a#] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [c#] ; Speichert das Ergebnis in cy# . fstp qpt [s#] ; Speichert das Ergebnis in sy# EndFunc
Proc P_SinCos2() Naked . fld qpt [sc.a] ; Lädt den Wert v# erneut auf den FPU Stack . fsincos ; Berechnet den Kosinus von v# erneut . fstp qpt [sc.cos] ; Speichert das Ergebnis in cy# . fstp qpt [sc.sin] ; Speichert das Ergebnis in sy# EndProc
|
|
|
Post by Roger Cabo on Jan 12, 2024 15:24:58 GMT 1
I think 7 is not always the fastest and with fluctuations because of the sc.a = Timer.. this is a system API call. Who knows how many thread accessing this function at the same time.. because must be thread save while the hardware push a new time into.. and this will be done in nanoseconds..
But perhaps you can try to input sc.a = sc.sin
I use an AMD CPU and floating point instructions are faster than Intels over all. Since 1986 I used DX50? Intel.. And this is the first time I brought an AMD and I'm really amazed of 110% stability and over all performance. My Intel PC crash a lot more, I must sadly admit. Intel is a bit tired of CPU innovations and does not handle heat that well.
|
|