Sinus und Cosinus schnell bekommen.



  • Hallo

    Ich brauche für ein Projekt Sinus und Cosinus, jedoch müssen die sehr schnell sein. Heisst: Ich kann math.h vergessen.
    Der Vorteil: Das Ergebnis muss nicht so genau sein (3 - 5 Nachkommastellen reichen). Approximieren ist doch auch langsam, oder?

    Wie soll ich das nun anstellen?



  • Muss es über feste Werte oder per Laufzeit mit variablen Werten berechnet werden?


  • Mod

    EOutOfResources schrieb:

    Hallo

    Ich brauche für ein Projekt Sinus und Cosinus, jedoch müssen die sehr schnell sein. Heisst: Ich kann math.h vergessen.

    Wow, für jemanden der so dringend Geschwindigkeit braucht, dass math.h nicht mehr ausreicht, ist es erstaunlich, dass er sowas fragen muss. Besonders nachdem du schon mal das Netz nach schnellen Sinusalgorithmen durchsucht haben dürftest (hast du doch, oder? 😉 )

    Der Vorteil: Das Ergebnis muss nicht so genau sein (3 - 5 Nachkommastellen reichen). Approximieren ist doch auch langsam, oder?

    Aber wenn du weniger Stellen genau haben musst, dann kann das durchaus schneller sein als die Funktion in der Standardbibliothek. Du könntest zum Beispiel eine Tabelle mit vorberechneten Werten nehmen und grob linear approximieren. Oder eben einen der vielen approximativen Algorithmen aus dem Netz benutzen.

    Das musst du aber wahnsinnig effizient implementieren, wenn du die Standardbibliothek schlagen willst. Möglicherweise wirst du zu Assemblertricks greifen müssen.



  • Warum kannst du cmath vergessen? Hast du die Performance wirklich als Schwachstelle gefunden?
    Und ansonsten eben approximieren. Wenn die Approximation nicht schneller ist, als das exakte berechnen, dann bringt sie ja wohl nicht viel. 😉

    Schau mal hier:
    http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/

    Vielleicht hilft dir das was.



  • Für sowas verwendet man Lookup-Tabellen.



  • wenns auf Speicher nicht ankommt, bau dir am Programmstart ne LUT (lookuptable). Weiss ja nicht wie genau es werden soll, aber wenn du dir für den Wertebereich [0...90.0] die Werte einmal berechnest kannst du den Rest über Symetrie lösen: http://upload.wikimedia.org/wikipedia/commons/7/71/Sine_cosine_one_period.svg

    Andererseits glaube ich nicht wirklich das die Mathefunktionen ein bottleneck darstellen ...



  • padreigh schrieb:

    bau dir am Programmstart ne LUT (lookuptable).

    Eigentlich generiert man über ein Script eine Datei, die die Werte readonly als Array hält.



  • Geht es darum von irgendwelchen Werten immer wieder Sinus/Cosinus zu bestimmen, oder geht es darum eine kontinuierliche Sinus/Cosinusschwingung zu generieren? Für letzteres gibt es sicher schnelles.



  • Tim schrieb:

    Geht es darum von irgendwelchen Werten immer wieder Sinus/Cosinus zu bestimmen, oder geht es darum eine kontinuierliche Sinus/Cosinusschwingung zu generieren? Für letzteres gibt es sicher schnelles.

    Ich habe willkürliche Werte und nicht eine schöne Welle.

    Ich hab mir mal den Link von drakon angeschaut und eine Funktion davon gemacht. Auch eine Funktion habe ich von der Approximations-Methode und der LookUpTable-Methode gemacht(LUT ist auf dem Heap).

    Gemessen(mehrere Durchläufe), verglichen und das knapp schnellste ist die LUT-Methode. Und für meine Bedürfnisse ist sie wohl das besste.

    Vielen Dank für die tollen Vorschläge.



  • Falls mehrere sin/cos-Werte a la sin(ax+b), cos(ax+b) für versch. Ganzzahlen x berechnet werden sollen, kann man das auch noch beschleunigen.



  • EOutOfResources schrieb:

    Gemessen(mehrere Durchläufe), verglichen und das knapp schnellste ist die LUT-Methode.

    Postest du deinen code?


Anmelden zum Antworten