Sin und Cos schneller machen? (SIMPEL)
Übersicht

![]() |
FirstdeathmakerBetreff: Sin und Cos schneller machen? (SIMPEL) |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn ihr nicht immer eine so hohe Genauigkeit beim Sinus und Cosinus braucht, und es um ca 60% schneller machen wollt, dann ist folgende Methode vielleicht das Richtige für euch:
Für jedes Grad speichert ihr die Cosinus und Sinus Werte einfach in einem Array. Das bringt zwar im Debugmodus keinen Vorteil, aber bei der finalen Exe Kostet euch ein Aufruf viel weniger Zeit, was sich bei vielen unvermeidbaren Aufrufen rechnet. SinCosFast.bmx Code: [AUSKLAPPEN] Const SINCOSFASTDEGREE:Int = 360 Global SINFASTARR:Float[SINCOSFASTDEGREE] For Local i:Int = 0 Until SINCOSFASTDEGREE SINFASTARR[i] = Sin(i) Next Function SinFast:Float(deg:Int) Return SINFASTARR[(SINCOSFASTDEGREE + deg Mod SINCOSFASTDEGREE) Mod SINCOSFASTDEGREE] End Function Function CosFast:Float(deg:Int) deg:+ 90 Return SINFASTARR[(SINCOSFASTDEGREE + deg Mod SINCOSFASTDEGREE) Mod SINCOSFASTDEGREE] End Function Performance Test Code: [AUSKLAPPEN] superstrict Include "SinCosFast.bmx" Const times:Int = 10000000 Const turns:Int = 10 Global numbers:Float[1000] For Local i:Int = 0 Until numbers.length numbers[i] = Rnd(0,360) Next Delay 100 Global time:Int[3] Global timeglobal:Float[3] For Local t:Int = 0 Until turns time[0] = MilliSecs() For Local i:Int = 0 Until times Sin(numbers[i Mod numbers.length]) Cos(numbers[i Mod numbers.length]) Next time[0] = MilliSecs() - time[0] time[1] = MilliSecs() For Local i:Int = 0 Until times SinFast(numbers[i Mod numbers.length]) CosFast(numbers[i Mod numbers.length]) Next time[1] = MilliSecs() - time[1] Local a:Float time[2] = MilliSecs() For Local i:Int = 0 Until times a = numbers[i Mod numbers.length] a = numbers[i Mod numbers.length] Next time[2] = MilliSecs() - time[2] Print "local times" Print time[0] Print time[1] Print time[2] timeglobal[0]:+ time[0] timeglobal[1]:+ time[1] timeglobal[2]:+ time[2] Next timeglobal[0]:/turns timeglobal[1]:/turns timeglobal[2]:/turns Print "---------------------------------------" Print "Average for sin cos : " + timeglobal[0] Print "Average for sinf cosf : " + timeglobal[1] Print "Average for just frame: " + timeglobal[2] Print "" Print "One Call of Sin + Cos : "+(1000000 * Float((timeglobal[0] - timeglobal[2])) / times)+"ns" Print "One Call of SinFast + CosFast: "+(1000000 * Float((timeglobal[1] - timeglobal[2])) / times)+"ns" Zeiten bei mir (times = 10000000, turns = 10) NONDEBUG Average for sin cos : 1461.19995 Average for sinf cosf : 593.299988 Average for just frame: 16.3999996 One Call of Sin + Cos : 144.479996ns One Call of SinFast + CosFast: 57.6899986ns DEBUG Average for sin cos : 2062.60010 Average for sinf cosf : 2317.10010 Average for just frame: 710.799988 One Call of Sin + Cos : 135.180008ns One Call of SinFast + CosFast: 160.630005ns "just frame" ist das Framework drumherum, also die Schleifenaufrufe etc. Die Zeit habe ich versucht annähernd zu berechnen, damit man sich die reine Aufrufzeit der Funktionen berechnen kann (zweiter Werteblock). |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
- Zuletzt bearbeitet von Firstdeathmaker am Do, Okt 15, 2009 8:36, insgesamt 2-mal bearbeitet
![]() |
SpionAtom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jun 14, 2004 | ||
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080 |
![]() |
mpmxyz |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm... Wo ist der "Performance Test" hin?
Hat der sich versteckt? ![]() Und wenn auch schon "zu große" Winkel beachtet werden, sollten meiner Meinung nach auch negative Winkel bei der Index-Bestimmung berücksichtigt werden, wenn das dann nicht zu langsam ist: Code: [AUSKLAPPEN] (SINCOSFASTDEGREE + deg Mod SINCOSFASTDEGREE) Mod SINCOSFASTDEGREE
So bleibt der Index immer in den erlaubten Grenzen. Wenn 1°-Schritte zu ungenau sind, kann man die Genauigkeit erhöhen, indem man den Code nur noch leicht anpasst. (SINCOSFASTDEGREE vergrößern und jeden Winkelwert mit einem Faktor von "SINCOSFASTDEGREE/360.0" multiplizieren oder eine Einheit "360°/SINCOSFASTDEGREE" entsprechen lassen) Aber spätestens dann kann es sich lohnen, zu beachten, dass "Cos(a+90°)=Sin(a)" gilt. Man braucht dann nur noch eine Wertetabelle. (Das wurde auch in dem von SpionAtom genannten Thread gesagt) Sonst habe ich aber nichts dran zu meckern. ![]() Das Vorspeichern von Sinus und Cosinus kann einiges an Geschwindigkeit bringen. In Blitz3D spare ich ca. 96% der Rechenzeit und habe eine Genauigkeit von 0.001°. (Ich habe hier leider kein BlitzMax zum Testen) Wie schnell wäre es, wenn man den Code nach dem "Return" direkt dahin schreiben würde, wo es gebraucht wird? Es wäre nämlich blöd, wenn die Geschwindigkeit zu sehr durch den Funktionsaufruf verlangsamt wird. mfG mpmxyz |
||
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer |
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Habs berichtigt.
@ SpionAtom: Den Thread hab ich nicht gefunden, hatte nur im Codearchiv gesucht, nicht aber in den normalen Threads. Naja, meine Version ist schließlich "ready to use". |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group