Ich habe festgestellt, dass floating point Berechnungen für Division und Addition recht langsam sind. Uint64 ist ebenfalls echt lahm. Es geht darum, dass ich Register für eine PLL im avr berechne für gegebene Frequenz. Kann man floating point Operationen und uint64 Operationen irgendwie mit dem avr GCC beschleunigen?
Die Arbeitswerte einer PLL werden üblicherweise berechnet, um damit eine gewünschte Frequenz aus einer gegebenen Referenzfrequenz abzuleiten. Bis sich die gewünschte Frequenz einstellt, vergehen schon mal einige ms. Oder deutlich mehr, wenn es tiefere Frequenzen sind. Welche Anwendung könnte Probleme bekommen, wenn die Berechnung nicht viel schneller, als die Einschwingzeit einer PLL ist? Wann kann man denn die Wunschfrequenz überhaupt nutzen?
Nils E. schrieb: > Kann man floating point Operationen und uint64 Operationen irgendwie mit > dem avr GCC beschleunigen? Was hast du von einem 8 bit uC ohne floating point hardware erwartet ? So ein Ding schafft halt nur so 1000 -10000 floating point operationen pro Sekunde. Bei uint64 sollte zumindest addition und subtraktion schneller sein. Der normale Weg ist, dass man seine Software und die verwendeten Algorithmen an den Prozessor anpasst. Fixed point in 32 bit wäre oft eine Lösung. Tabellen mit linearer interpolation sind eine weitere.
MaWin schrieb: > Nils E. schrieb: >> Kann man floating point Operationen und uint64 Operationen irgendwie mit >> dem avr GCC beschleunigen? > > Was hast du von einem 8 bit uC ohne floating point hardware erwartet ? Endlich mal etwas was früher nicht besser war: da gab es auf 8-bitter hauptsächlich BASICs mit ausschliesslich Ganzzahlarithmetik, obendrein nur zu einstelligem MHz Takt. Da macht son Microchip ATMega doch eine ganz jute Fijur her.
Ich verstehe die Problematik nicht. Ich habe schon zig PLLs und DDS mit dem AVR angesteuert. Ganzzahlig und fraktional. Nie bin ich auf dieses Problem gestoßen. Das macht float-Divisionen zwar nicht schneller, zeigt mir aber, dass Du möglicherweise das Problem falsch angehst. Da Du die Rechenoperationen nicht viel schneller bekommen wirst, wäre der Ansatz nun also, den bisherigen Ansatz zu überdenken. Und warum muss es schnell sein? Um welche PLL geht es denn? Und was ist Dein Ziel und wie willst Du es im Moment lösen? Gruß Jobst
Jobst M. schrieb: > Um welche PLL geht es denn? Und was ist Dein Ziel und wie willst Du es > im Moment lösen? Ich habe mir einen Kabeltester gebaut, der auf einen Sweep von mehreren Frequenzen angewiesen ist und da will ich die Einstellzeit für einen neuen Punkt eben möglichst klein halten. Die PLL braucht laut Datenblatt nicht mehrere Millisekunden, sondern eher 300µs im Fast-Lock Modus.
Zeig doch mal das Programm, das haufenweise float dividieren muß. Man kann z.B. konstante Berechnungen aus der Schleife heraus ziehen oder mit dem Kehrwert multiplizieren.
Wenn es spezifisch um sweeps mit konstantem Frequenzraster geht, lässt sich mit den "exact frequency modes", welche viele PLL ICs bereitstellen, ebenfalls viel Rechenaufwand sparen. Vieles kann dann im Voraus berechnet werden. Ausserdem würde ich eher mit Uint64/32 und in Hz rechnen ststt Floats zu verwenden
> Uint64 ist ebenfalls echt lahm.
Das habe auch ich schon festgestellt. Beispiel:
Bei einer 32x32->64 MUL werden die Operatoren zuerst auf 64 Bit
erweitert und dann multipliziert, mit der Folge, dass statt der
notwendigen 16 Multiplikationen 64 ausgeführt werden, davon 48 mit 0,
die man sich (samt den unzähligen ADDs und ADCs danach) sparen könnte.
Zumindest war das vor einigen Jahren so, als ich mir das anschaute.
Da gibt es noch deutliches Optimierungspotential, d.h. es müsste mal
Hand angelegt werden.
> von mehreren Frequenzen Wenn es endlich viele sind, schreibt man die Werte in eine Tabelle und ist fertig. Das kann selbst ein uralter und langsamer PIC. Der rechnet sich auch keinen Bruch dabei.
Tippgeber schrieb: >> Uint64 ist ebenfalls echt lahm. > Das habe auch ich schon festgestellt. Dass eine 64-Bit Multiplikation auf einem 8-Bitter langsamer als eine 24-Bit Multiplikation ist, wird sicherlich nicht überraschen.
Tippgeber schrieb: > Bei einer 32x32->64 MUL werden die Operatoren zuerst auf 64 Bit > erweitert und dann multipliziert, mit der Folge, dass statt der > notwendigen 16 Multiplikationen 64 ausgeführt werden Welche Plattform, welcher Compiler?
Hier findet sich ein Beispiel, wie sich Floatingpoint Divisionen mit einer Kombination aus Mathematik und Bitfummelei vermeiden lassen. Wenn man einen ausreichend genauen Näherungswert akzeptiert. https://www.heise.de/newsticker/meldung/Zahlen-bitte-0x5f3759df-merkwuerdige-Mathematik-im-Egoshooter-3208927.html
Weshalb soll jedes mal gerechnet werden ? Zum einen kann man diese Frequenzen einmal rechnen und dann die Werte aus einer Tabelle nehmen. Zum anderen kann man interpolieren zwischen ein paar Stuetzstellen. Ein paar Frequenzen fuer einen Sweep ... man kann uebertreiben.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.