Festkunktmagie mehr als Abra Kadabra?

Hallo,

dachte darüber nach für Berechnung Festkomma-Arthmetik zu nutzen.

Nun hatte ich bereits drei Ideen der Implementierung und ist gibt bestimmt weitere. Die Frage ich habe, ist welche ist am Sinnvollsten?
Dafür mussen ja, bisherige Typen umgedeutet werden.
Die erste Idee, die ich bisher daher hatte, ist in einer zu schreibenen Mathebiblothek, die Anzahl aller Nachkommastellen zuübergeben, sodass man eine Dezimal darstellte Zahl durch 10^n Teilen muss, und schon hat man die ganze Zahl, der Rest die Nachkommastellen.
Alternativ, könnte man auch die Anzahl der bits hinterlegen, und die Zahlen in binärer Darstellung uminterpretieren mithilfe von bitweiser Logik.
Zu guter Letzt könnte Man auch auf die Hinterlegung in einer Biblothek verzichten und in einem Klassentypen den Ganzahlanteil als und die Nachkommastellen als einzelne Attribute hinterlegen, bei letzter wieder mit Bitweiser Logik umgedeutet werden müsste...(?)
Dann wäre zum Beispiel (100, 0x7) das äquivalent zu 100.5.

Was haltet ihr von den Idee? Die letzten beiden verbrauchen für mich zu viel Rechenaufwand. Kann man das Problem auch noch effizenter Lösen?

Mit freundlichen Grüßen,

Mummel

Auf Gleitkommazahlen komplett verzichten. Für die meisten Sachen ist es übehaupt nicht notwendig.

Beispiel Temperatur:
10.66°C

Warum soll man sich diesen Wert umbedingt in ein float packen? 1066 reicht hier doch vollkommen aus. Man sollte es nur einheitlich halten. Die Ausgabe ist später mit Div und Mod leicht auszugeben.

Eine allgemeingültige Lösung ist immer eine, die "zuviel Rechenaufwand" braucht. :slight_smile:
Da das Optimum zu finden, ist sehr individuell.

Wenn es dir nur um Zahlen im Bereich -100.00 .. 100.00 geht, ist eine

struct {char ganz; byte nachkomma;} nur halb so groß wie einfloatund genauso groß wie einint im Bereich -1000 .. +1000.

Fragt sich, was du damit machen willst:
-Speichern (struct / int)
-Anzeigen (struct)
-Rechnen (int) ( Mittelwert, Änderungsgeschwindigkeit, ... ? dann evtl. doch eher float ?)

Warum du den Wert für "100.5" als {100, 0x07} speichern willst, verstehe ich nicht.
Oder soll das Darstellungsformat (Anzahl Nachkommastellen) im Wert mit codiert sein?

Hängt vom Anwendungsfall ab, ob das sinnvoll oder gar notwendig ist.

Bei meinen Matrix-LED-Animationen mache ich alles mit 8 oder 16 bittigen Ganzzahlen. Wo das Komma ist, ist für mich nicht relevant, bzw. ich weiß es vorher, oder ich speichere es in den untersten Bits (soviele, wie ich eben brauche). Eventuelle Vorzeichen genauso.

Das geht auf jeden Fall schneller, aber macht den Code teilweise schwer nachvollziehbar - da ist eine aussagekräftige Dokumentation gefragt, welche erklärt, WARUM man was macht.

Multiplikation/Division mit/durch Zweierpotenzen konsequent durch bitschiften zu ersetzen, spart zusätzliche Rechenzeit.

Sehr gern benutze ich auch die Ganzzahl-Mathebibliothek von FastLED. Die Ergebnisse sind teilweise nicht die exaktesten (z.B. die approximierten Winkelfunktionen - ich würde das also nicht für ein Mondflugprogramm benutzen...), aber so ziemlich die Schnellsten, die man bekommen kann.

Gruß,

Helmuth

Mummel:
Was haltet ihr von den Idee? Die letzten beiden verbrauchen für mich zu viel Rechenaufwand. Kann man das Problem auch noch effizenter Lösen?

Die Arduino-Libraries bringen schon recht effiziente Routinen zum Rechnen mit 8-, 16-, 32- und 64-Bit Ganzzahlen (signed und unsigned) sowie von 32-Bit Gleitkommazahlen ("float") mit.

Was ist denn das Problem?

Kannst Du das Problem beschreiben?`

Ich hasse meine Maus, zu im Forum schreiben nervig, wieder alles weg...

Vielen Dank für eure Nachrichten. Ich schaue mir gleich Mal die FastLED genauer an (nur Mal kurz bisher überflogen.

jurs:
Die Arduino-Libraries bringen schon recht effiziente Routinen zum Rechnen mit 8-, 16-, 32- und 64-Bit Ganzzahlen (signed und unsigned) sowie von 32-Bit Gleitkommazahlen ("float") mit.

Was ist denn das Problem?

Kannst Du das Problem beschreiben?`

Dennoch sind Berechnungen mit Fließkomma-Zahlen noch um ganzes Stück langsamer. Nur das Teilen durch Integer soll langsamer sein.

Warum möchte ich das eigentlich? Zum einem immer um es Mal gemacht und verstanden zu haben. :slight_smile: Finde ich bei Arduino immer ganz wichtig, dazu ist es ja auch da. Zum Anderen möchte ich möglichst schnell über viele Korridanten des Typs (X,Y, Alpha) rechnen. Brauche dafür Winkelfunktionen etc. Nun habe ich schon Mal vorläufig ein Modul in C geschrieben. Dabei war die C- für Short schon unoptimiert 40% oder so schneller, mit etwas Optimierung und Durchschnittlich 3% Abweichung kam ich bisher auf 60% kürzere Rechenzeit.
Vergleichen zur Standard cos-Funktion, dabei habe ich je nach Winkel bisher nach dem fünften oder dritten Glied des Taylor-Polynoms abgebrochen. Habe dabei dann Berechnungen nur noch von 0 bis 90° berücksichtigen gehabt und es geht gewiss noch besser und auch schneller... Durchschnitt immer bezogen auf Tausende von Cos-Berechnungen.

Aber da ich sowie das Modul als C++-Biblothek umschreiben wollte, dachte ich, dass eine gute Grundlage wichtig ist und wollte daher nochmal nachfragen, wie die Festkommazahlen am Besten nutze, damit es am Ende nicht an den Grundlagen krankt. Habe mich nun in C++ eingelesen und fühlte mich langsam Bereit es zu versuchen.

Liebe Grüße und vielen Dank!

Mummel:
Dennoch sind Berechnungen mit Fließkomma-Zahlen noch um ganzes Stück langsamer. Nur das Teilen durch Integer soll langsamer sein.

Divisionen sind auf den 8-bit Atmega Controllern deshalb so langsam, weil es dafür keine Hardware-Recheneinheiten auf diesen Controllern gibt.

Hauptsache, Du versuchst nicht, mit irgendwelchen Standarddatentypen Divisionen zu machen und dabei schneller zu sein als die Standardfunktionen von GCC. Denn die Divisionen mögen zwar relativ langsam sein, aber sie sind in den GCC Libraries in Form von handoptimierten Assemblerfunktionen realisiert, und da dürftest Du mit C-Programmierung nicht mal ansatzweise drankommen.

Die Verwendung eigener Math-Funktionen dürfte sich also nur allenfalls in speziellen Sonderfällen zeitlich rechnen, z.B. bei Winkelfunktionen mit Integer-Lookup-Tabellen und begrenzter Auflösung.

jurs:
Die Verwendung eigener Math-Funktionen dürfte sich also nur allenfalls in speziellen Sonderfällen zeitlich rechnen, z.B. bei Winkelfunktionen mit Integer-Lookup-Tabellen und begrenzter Auflösung.

Um wesentlich geht es hierbei ja nicht. Allerdings werde ich eine Funktion statt einer Lookup-Tabelle nehmen. Das sollte etwas platz sparen und wenn man dann eine einfache Interpolation in die Lookuptabelle integriert, dann sollte sie auch nicht mehr schneller sein...

Aber nun sind wir vom eigentlichen Thema ganz abgekommen. Wie man die Festkommazahlen am Besten darstellt. Hier im Fall für das Spplatzsparende Speichern und schnelle Berechnen.

Liebe Grüße.

Ist doch reine Interpretationssache.

Alle Ganzzahlwerte kann man als Festkommawerte ohne Nachkommastellen betrachten.
Da muss man beim Rechnen nachher nicht die Nachkommastellen des Ergebnisses korrigieren,
da nie welche da sind oder entstehen.

Hat man Nachkommastellen (hier ja Bits) dann gelten die üblichen Verschieberegeln,
genauso wie im Dezimalsystem, halt nur mit Bits. 0,2 * 0,2 = 0,04 0,2 / 0,2 = 1,00

'Richtige' floats trennen nur Vorzeichen Exponent und Mantisse um den Bereich der Werte aufzuspreizen,
von der Mächtigkeit her (Anzahl der Elemente) sind long und float eigentlich gleich,
einige mögliche float Werte werden aber nicht benutzt, sondern durch Normalisierung
in eine andere Form mit gleichem Wert gebracht.

Es gibt also weniger unterschiedliche float-Werte als long Werte.

Ob man mit 1/10 1/100 1/256 1/8 Werten arbeitet ist völlig egal,
solange man beachtet das 1/10 * 1/10 = 1/100 oder 1/16 * 1/16 = 1/256 ergibt,
also nacher teilen/multiplizieren bzw. rechts/links shiften.

Bei Addition/Subtraktion verschiebt sich das Komma nicht,
also alles wie bei Adam Riese.

Vielen Dank für den letzten Hinweiß,

spricht also für ein extra Klasse mit Operatorüberladung.

Das shiften Spricht dafür ja, dass man die Zahlen in Binärer Darstellung uminterpretiert. Was die Zahlen unlesbar macht...

Oder man geht den Kompromis ein, dass die Zahl dann noch dezimal lesbar ist, dann aber beim verschieben, einen Fehler macht von 1024/1000.

Gefällt mir beides nicht ganz so^^

Man bekommt nichts umsonst.

Das direkte Erkennen der Werte in einer BCD Darstellung ist zwar vorteilhaft,
wiegt aber meiner Ansicht nach nicht die 'Platzverschwendung' auf,
dafür kann man sie viel besser (dezimal) ausgeben/einlesen.

Fixkommazahlen (auch binäre) kann man auch ganz gut auch aus einem Dump
abschätzen, etwas das mir bei echten floats schwerer fällt.

Binär lässt sich besser rechnen, ist halt eine Frage was überwiegt.

Relevant wird das aber erst wenn man sehr lange Zahlen manipulieren muss.

Hallo,

ich habe mich Mal (endlich) an die Implementierung einer Klasse gemacht. Ich werde den Code einmal anhängen. Leider ist das Ergebnis noch nicht das, was es sein soll. Ich habe auch einen Testtreiber geschrieben um damit zu debuggen (CodeBlogs mit g++ im 2011er Standard, Arduino habe ich auch auf den 2011 eingestellt).
Leider kommt im entsprechenden Sketch schon Mal nicht Mal mehr das selbe heraus, obwohl nochmal nachgesehen habe, ob die Ausdrücke möglichst gleich sind und möglichst viel Code direkt kopiert.

Das andere Problem ist im Sketch, dass ich testen wollte, wie schnell der Code läuft. Daher habe möglichst viele Berechnungen mit Multiplikationen und Divisionen durchgeführt, damit sich die erster und letzter Zyklus der For-Schleife möglich wenig auswirken. Genau 16.000 Berechnungen habe ich durchgeführt, da dass Board, dass ich zum Testen genommen habe Mega 2560 mit 16MHz getracktet ist, sodass 1/16 µs * 16.000 Operationen * x Zyklen pro Operation = Messzeit in ms ergeben sollte(?).

Die Messzeiten ergeben für mich aber keinen Sinn, da sie viel zu kurz sind für Double und viel zu lang für den/die neu implementierten Typen/Klasse. Woran mag das liegen.
Werden die Double-Berechnungen herausoptimiert? (Wenn ja, wie kann ich das verhindern?)
Liegt die langsame Rechenzeit an der Implementierung als Klasse, oder im Code selbst? Wie kann ich die Laufzeit verbessern? (Wenn ich nicht zumindest in die Nähe der Laufzeit vom Double komme, macht die ganze Übung für mich nur noch als Übung Sinn) :frowning: .

Versteht jemand warum im Sketch die Berechnungen nicht richtig ausgeführt werden?

Mit freundlichen Grüßen,

Mummel

Fixed16_t.zip (266 KB)

Ohne mir deinen Code angesehen zu haben: ich habe mich auch schon oft am Kopf gekratzt, warum Benchmarks manchmal irritierende Ergebnisse liefern.

Das passiert gelegentlich, weil der Compiler "sinnlose Berechnungen" einfach wegoptimiert.

Also mit den Ergebnissen auch irgendetwas machen, z.B. in ein Array legen und NACH dem Messen der Zeit irgendwohin senden.

Das Array muss nicht groß sein, man kann auch in einem kleinen rumiterieren. Hauptsache, es wird nicht wegoptimiert.

Beste Grüße,

Helmuth

Mummel:
Versteht jemand warum im Sketch die Berechnungen nicht richtig ausgeführt werden?

Erwartest Du jetzt ernsthaft, dass sich jemand 265.68 KB ZIP-komprimierten Library- und Sketch-Code anschaut und debuggt (das sind entpackt ja bestimmt über 700 KB) , wo irgendein Rechenfehler zu einem mathematischen Problem liegt, das Du nicht mal ansatzweise erklärt hast.

Ich habe in diesem Thread überhaupt nicht verstanden, weshalb Du mit den Standard-Datentypen für 16- und 32-Bit 'int' (signed/unsigned) und 32-Bit 'float' für Deinen Anwendungsfall nicht klarkommst und woran es hapert.

Ich habe weder verstanden, welchen Wertebereich und wieviele signifikante Stellen Genauigkeit Du brauchst, und weshalb das, was Du machen möchtest, mit Standard-Datentypen nicht schnell und einfach möglich sein sollte.

Was ich hier im Forum immer wieder sehe ist die Verwendung von 'float' ohne die geringste Notwendigkeit. Zum Beispiel gibt es hier immer wieder Leute, die digitale Temperatursensoren mit einer bestimmten integer-Temperaturauflösung von 9, 10, 11 oder 12 Bits verwenden, und nachdem diese Bits aus dem Sensor ausgelesen sind, die Temperatur (oft mit Hilfe einer "Library" als "float" bekommen möchten. Dabei wäre beispielsweise zur Darstellung eines Temperaturbereichs von −273,15 °C bis +273,15 °C mit Hundertstelgrad-Auflösung gerade mal eine 16-Bit Integerdarstellung notwendig, wenn man den Wert in Hundertstelgrad rechnet: Also statt −273,15 float −27315 als int, und statt +273,15 float 27315 int. Das einzige, was man dann benötigen würde, wäre eine Funktion, um so einen Ganzzahlwert in "Hundertstelgrad" in menschenlesbarer Form "wie eine Gleitkommazahl formatiert" mit Dezimalpunkt auszugeben.

Ich weiß nicht, was Dein konkretes Problem ist, aber um Anwendungen zu erstellen, die beispielsweise mit "Temperaturen in hundertstel Grad" oder mit "Spannungsangaben in Millivolt" zu rechnen, braucht man nichts weiter als Ganzzahl-Arithmetik mit int- oder long-Datentypen und ggf. eine spezielle Formatierungsfunktion für die menschenlesbare Ausgabe, falls man z.B. auf einem Display eine Spannungsangabe nicht als
2347 mV sondern als
2.347 V darstellen möchte.

Dazu braucht es im Programm keine einzige Gleitkommazahl.

Hallo,

ich habe versucht mir die beiden letzten Kommentare zu Herzen zu nehmen und nun versucht Sie zuberücksichtigen. Warum ich auf die Fragestellung kam ist, dass für eine Anwendung gewissermaßen nebenläufig ständig Winkelfunktionen berechnen möchte und das ganze am Ende mit einer warte Warteschlange vergleichen.
Mit nebenläufig meine ich, dass noch anderes getan werden soll die ganze Zeit triggernomsiche Funktionen zu berechnen. Was diese Ergebnisse braucht, aber nicht davon behindert werden darf... Also warten muss, aber nicht zu lange warten soll.
Dadurch dass ich Winkelfunktionen nehmen wollte, ist die Sache nicht ganz so einfach, dass ich nicht einfach Mal einen Wert Mal tausend nehmen kann um von double eine genaue Integerzahl zu bekommen... da daraufhin ja die neu zu schreibende Winkelfunktion angepasst werden müsste.
Aber ich habe mir gerade in anberacht von jurs Kommentar wirklich sinnvoll ist, einen paar Schritte zurück zugehen und a) zu sehen, wie schnell berechnet denn der Arduino eine Winkelfunktion. b) eine Cosfunktion für Double zu schreiben, die vielleicht weniger genau ist, dafür aber vielleicht sogar schneller? Wenn das denn geht, als eine fertige Standardbiblothek. Nun gut die Funktion muss ja dafür genauer sein, und wird daher mehr Rechenzeit benötigen...
Im besten Fall kann ich mir den anderen scharm ja sparen(?).

Nun also zum Test der Cosinusfkt... Ich wollte sie mir folgendem Code testen:

  long startTime = millis();
  
  Serial.begin(9600);
  
  for(i = 16000; i>= 0; i--) {
    erg = cos(fastToRad(i));
    index = i % 10;
    ergReg[index]=erg;
    if(i==0)
      endtime = millis();
  }
  duration = endtime - startTime;
  Serial.print("averaged cos took: ");
  Serial.print(duration);
  Serial.println(" cycles");

Schön und gut, blos als Ergebnis 6 Zyklen herauskam. Ich glaube, das selbe Ergebnis, wie bei dem Test der Rechenzeit double * double, was schon nicht sein konnte und bei einer Cos funktion kann das noch weniger sein... Daher habe ich auch exta den Array ergReg eingebaut. Was aber nichts brachte...
Woran mag das liegen?

Bei der berechnung für die selbst geschriebene Cos-Funktion kamen lausige 2262 Zyklen heraus. :frowning: Aber ich kann das nicht Mal vergleichen, wie schlecht es ist. Allerdings wären das für 256 cos Berechnungen 3.6 ms. Womit ich leben könnte. Wenn ich nur wüsste, wie es mit den Normalen Cosfunktion aussieht?

Übrigens beim zip letztens machte weit über 90% die Größe des Zips... der Testtreiber aus...

Wenn ihr mir einen Tipp geben könntet, was die Ermittlung der Rechenzeit der Cosfunktion angeht, wäre ich euch sehr dankbar. Liebe Grüße und bis zum nächsten Mal.

Mummel:
r mir einen Tipp geben könntet, was die Ermittlung der Rechenzeit der Cosfunktion angeht, wäre ich euch sehr dankbar.

Mein erster Tipp wäre: Mache wenigstens erstmal bei den einfachen Sachen keine gravierenden Fehler!

Zum Beispiel hier:

  duration = endtime - startTime;
  Serial.print("averaged cos took: ");
  Serial.print(duration);
  Serial.println(" cycles");

Die Differenz zwischen endtime in Millisekunden und startTime in Millisekunden ergibt bei Dir "cycles"?
Was ist das denn?

Das wäre ja wie "Fünf Äpfel weniger drei Äpfel ergibt zwei Mangos".

Oder 10 Äpfel weniger fünf Äpfel ergibt fünf Erdbeeren, oder sowas?

Das kann einfach nicht sein, dass Du eine Differenz zwischen zwei Zahlenwerten in einer Einheit bildest (z.B. in Millisekunden), und die Differenz ist dann irgendwas anderes (z.B. "cycles", "Mangos", oder "Erdbeeren".

So funktioniert das nicht. Eine Zeitdifferenz zwischen zwei Zeiten in Milliselunden ergibt natürlich auch wieder Millisekunden!

Zweiter Tipp: Poste Beispielcode, der sich auch fehlerfrei kompilieren läßt!

Die in Deinem Code verwendete Funktion fastToRad gehört nicht zur Arduino Core-Library und auch nicht zur AVR-LIBC Library, also was ist das?

Wegen des Benchmark-Timings für "float", habe ich gerade mal ein bischen herumgespielt und bin auf ungefähr folgende Größenordnung auf einem UNO-Board mit 16 MHz gekommen:
- float-Addition ca 11µs
- float-Multiplikation ca. 12 µs
- float-Cosinusberechnung ca. 110 µs

Wobei wenn man wie in Deinem Beispielcode im Vollkreis überhaupt nur 360 verschiedene Cosinuswerte von ganzzahligen Gradwerten benötigt (einen für jede Gradzahl), könnte man das zeitlich mit einer Nachschlagetabelle sicher optimieren: Um für 360 Grad alle Cosinuswerte zu erhalten, brauchst Du nur eine Nachschlagetabelle mit 90 Werte (ein Viertelkreis), und kannst daraus jeden anderen Cosinuswert einer ganzzahligen Gradzahl einfach durch Negierung und Subtraktion von 1 ableiten.

Das dürfte dann deutlich unter 110µs dauern, aber dafür braucht es 90*4=360 Bytes extra RAM (und der volle Geschwindigkeitsvorteil ergäbe sich nur bei ganzzahligen Gradzahlen als Parameter).

jurs:
aber dafür braucht es 90*4=360 Bytes extra RAM (und der volle Geschwindigkeitsvorteil ergäbe sich nur bei ganzzahligen Gradzahlen als Parameter).

Wieso RAM?

Die Tabelle kann doch prima im PROGMEM geparkt werden, wenn sie einmal berechnet ist.

Gut Whandall, da müsste man erstmal testen wieviel Zeit das spart, wenn es im Flash ist! Aber Danke. Ist erstmal eine Frische Idee...

@jurs Die Zeiten haben mir erstmal sehr geholfen. In der letzten Ausbaustufe, war nun meine eigene double cos-Funktion um 10 % Langsamer als deine Messzeit und wenn ich nur den Bereich bis 360° Begrenze ist mein Code genauso schnell. :((
Mein eigener Typ für Double Multiplikationen ist bisher viermal so langsam, bringt also erstmal gar nichts. Wobei es für mich eigentlich sehr interessant wäre, woran, dass liegt umd was man dagegen tun könnte. Ich werde dann aber erstmal als nächstes die LookupTabelle versuchen. Wobei 110 µs gar nicht mal so schlecht ist.

Nun zu den Äpfel und Birnen. Meine Überlegung wie man dann auf durschnittliche Zyklenzahlen kommen möchte, habe ich schon versucht in meinem vorletzen Post darzustellen.

Ich gehe davon aus, dass eine große Anzahl von einer Berechnungen die Messzeit derart dominiert, dass Sie ist groß ist gegen die Messzeiten alle anderen möglichen Operationen, die gerade noch so laufen könnten.

Dabei gehe von der Formell aus:

1/ Takt * Anzahl der Wiederholungsrechnungen * Anzahl der Zyklen pro Wiederholungsrechnung = Messzeit

Das heißt:

Zyklen pro Wiederholungsrechnung = Messzeit /(Anzahl der Wiederholungsrechnungen * 1/Takt)

Wenn ich nun die Messzeit in ms Messe und 16MHz des Uno oder Mega bei 16000 Wiederholungen berücksichtige komme ich auf:

durschnittliche Zyklenanzahl pro Wiederholungsrechnung = x ms/(16000 * 1/16 µs)
durschnittliche Zyklenanzahl pro Wiederholungsrechnung = x ms/(1000 * µs)
durschnittliche Zyklenanzahl pro Wiederholungsrechnung = x ms/ms

durschnittliche Zyklenanzahl pro Wiederholungsrechnung = x (also die gemessene Zeit in ms)

Liebe Grüße und vielen Dank fürs Posten.

Mummel:
Gut Whandall, da müsste man erstmal testen wieviel Zeit das spart, wenn es im Flash ist! Aber Danke. Ist erstmal eine Frische Idee...

@jurs Die Zeiten haben mir erstmal sehr geholfen. In der letzten Ausbaustufe, war nun meine eigene double cos-Funktion um 10 % Langsamer als deine Messzeit und wenn ich nur den Bereich bis 360° Begrenze ist mein Code genauso schnell. :((

Von was für "double" redest Du dabei? Sämtliche 8-Bit AVR-Controller rechen nur mit Datentp "float", und auch wenn Du für UNO, MEGA &Co. im Quellcode "double" schreiben kannst, ändert das nichts an den Rechnungen, denn float==double für alle 8-Bit Atmegas.

Hast Du Dir eine Library für den double Datentyp für 8-Bit Atmegas zusätzlich installiert? Oder verwendest Du ein 32-Bit Arduino-Board? Oder meinst Du float?

Nur die 32-Bit Controller wie der Arduino DUE können standardmäßig mit double rechnen.

Von welchen Arduino-Controllertypen redest Du hier, wenn Du Timings messen möchtest?

Mummel:
Mein eigener Typ für Double Multiplikationen ist bisher viermal so langsam, bringt also erstmal gar nichts. Wobei es für mich eigentlich sehr interessant wäre, woran, dass liegt umd was man dagegen tun könnte. Ich werde dann aber erstmal als nächstes die LookupTabelle versuchen. Wobei 110 µs gar nicht mal so schlecht ist.

Nun zu den Äpfel und Birnen. Meine Überlegung wie man dann auf durschnittliche Zyklenzahlen kommen möchte, habe ich schon versucht in meinem vorletzen Post darzustellen.

Ich gehe davon aus, dass eine große Anzahl von einer Berechnungen die Messzeit derart dominiert, dass Sie ist groß ist gegen die Messzeiten alle anderen möglichen Operationen, die gerade noch so laufen könnten.

Dabei gehe von der Formell aus:

1/ Takt * Anzahl der Wiederholungsrechnungen * Anzahl der Zyklen pro Wiederholungsrechnung = Messzeit

Das mit dem Takt verstehe ich nicht. Eine höhere Auflösung beim Timing erhältst Du vor allem, wenn Du anstelle der recht langsamen und auch ungleichmäßig zählenden "millis()" Zeitzählung (die millis() Funktion zählt mal 1 und manchmal 2 in einem Schritt hoch) schnelle Vorgänge lieber mit der höher auflösenden und gleichmäßig laufenden "micros()" Zeitzählung laufen lassen würdest. Die Auflösung von micros() liegt bei 16 MHz Controllertakt immer bei 4µs.

Hallo,

ja nutze einen Uno R3 mit dem Mega328P. Also double ist wirklich gleich float. Das ist wirklich etwas unpräsie.
Der Tipp mit dem micros() ist wirklich sehr informativ. Habe das nun als Array probiert, im Flash gespeichert ist's noch mal einen Zacken schneller, als wenn er den Ram laden muss. Bin sehr zufrieden. Mit meiner Messmethode komme ich auf Durschnittliche 70 µs, wenn ich es nur bis 360 Rechnen lasse etwa 55µs.

Muss mich dann nur noch um atan2 kümmern, aber dass nicht mehr heute. Ich bin sehr dankbar. Hat gut geholfen! Vielen Dank.