Hallo, ich habe eine Frage zu der Laufzeit der Funktionen "printf" bzw. "sprintf". Es ist ja bekannt, dass diese Funktionen sehr viele Taktzyklen benötigen können. Weiß zufällig jemand, wieviele Taktzyklen die Ausgabe von einem 16-Bit unsigned Wert unter der Verwendung des C166 Compilers von Keil benötigt? Wenn jemand Werte von einem anderen Compiler hat, würde mich das genauso interessieren. Grüße Maax
Na Bub dann mess halt. Portpin setzen, printf aufrufen, Portpin löschen. Messen, Rechnen, Fertig. Nichts geht schneller.
cyblord ---- schrieb: > Na Bub dann mess halt. Dran denken, dass das Ergebnis für verschiedene Werte reichlich unterschiedlich ausfallen kann, denn es sind da typisch Divisionsalgorithmen beteiligt, deren Laufzeit mehr oder minder stark von den tatsächlich verwendeten Werten abhängt.
Danke, genau das wollte ich wissen. Da ich aktuell kein Board zur Verfügung habe, hätte ich gefragt. Öfters sollten Sachen schnell gehen, damit man sich auf das Wesentliche konzentrieren kann - und es hätte ja sein können, dass sich schon jemand zu diesem Thema Gedanken gemacht hat.
@Jörg Danke für die Antwort - ich werde Tests mit mehreren Zahlen machen und mir so das Maximum ermitteln - das ist für mich am Interessantesten.
Maax schrieb: > @Jörg > Danke für die Antwort - ich werde Tests mit mehreren Zahlen machen und > mir so das Maximum ermitteln - das ist für mich am Interessantesten. Warum ist denn diese Zeit überhaupt kritisch? Meist handelt es sich dabei doch um eine menschenlesbare Ausgabe. Warum sollte die derart schnell sein müssen?
Das mit der menschenlesbaren Ausgabe ist richtig. Es ist nur so, dass ein Stück Code zyklisch mit hoher Geschwindigkeit durchlaufen wird (ca. 500 us), und im Fehlerfall soll eine Logausgabe erfolgen - sowas tritt von der Häufigkeit her alle paar Millionen Durchläufe auf. Und das printf soll dieses betreffende Stück Code nicht soweit aufblasen dass es nicht mehr in der geforderten Zeit (< 500 us) abgearbeitet werden kann.
Maax schrieb: > Das mit der menschenlesbaren Ausgabe ist richtig. Es ist nur so, dass > ein Stück Code zyklisch mit hoher Geschwindigkeit durchlaufen wird (ca. > 500 us), und im Fehlerfall soll eine Logausgabe erfolgen - sowas tritt > von der Häufigkeit her alle paar Millionen Durchläufe auf. Und das > printf soll dieses betreffende Stück Code nicht soweit aufblasen dass es > nicht mehr in der geforderten Zeit (< 500 us) abgearbeitet werden kann. Das sollte man anders lösen. Dann solte die Ausgabe einfach nicht in diesen kritischen Codeteil. Ein Fehlerflag setzen und Ausgabe in einem nicht kritischen Teil machen.
Wenn du nur eine 16bit unsigned int in einen String umwandeln willst, wird es wahrscheinlich schneller gehen wenn du eine Funktion schreibst die dafür optimiert ist und nicht eine eierlegende Wollmilchsau wie sprintf verwendest.
:
Bearbeitet durch User
Wenn ich sicherstelle, dass die Abarbeitung dieses Codeteils im Worst Case schnell genug ist, dann spricht meiner Meinung nach nichts dagegen. Deshalb mache ich mir Gedanken zur Laufzeit. Es kann theoretisch auch passieren, dass mehrere Logausgaben direkt hintereinander folgen. Dann wird es mit Flags setzen schon wieder komplizierter. Das einzige was so theoretisch passieren kann, ist dass der Puffer von der Uart überläuft wo die putchar reinschreibt.
Max H. schrieb: > Wenn du nur eine 16bit unsigned int in einen String umwandeln willst, > wird es wahrscheinlich schneller gehen wenn du eine Funktion schreibst > die dafür optimiert ist und nicht eine eierlegende Wollmilchsau wie > sprintf verwendest. itoa gibts ja schon. Die sollte schnell genug sein. > Wenn ich sicherstelle, dass die Abarbeitung dieses Codeteils im Worst > Case schnell genug ist, dann spricht meiner Meinung nach nichts dagegen. Ist halt unschön.
cyblord ---- schrieb: > itoa gibts ja schon. Die sollte schnell genug sein. Ändert aber nicht viel an der Dynamik der verwendeten Division. Der restliche Overhead von printf ist für den gleichen Formatstring dann wiederum konstant. Solange der Formatstring ist, wird sich das in Grenzen halten.
Jörg Wunsch schrieb: > Ändert aber nicht viel an der Dynamik der verwendeten Division. Die 16 Bit Division soll 20 Takte brauchen, was bei 25MHz dann 0,8µs wären. Das ist m.E. für die geplante Anwendung hinreichend schnell (Schätzwert < 30µs für itoa).
m.n. schrieb: > Die 16 Bit Division soll 20 Takte brauchen Kann ich mir in dieser Allgemeinheit für einen Prozessor ohne Hardware-Division nicht vorstellen. Wiederum: wenn dem so ist, dann wird auch printf keine Größenordnung langsamer sein. Das Parsen des Formatstrings kostet, solange keine Formatierungsanweisungen drin sind, nun auch keine Unmengen an Zeit.
Jörg Wunsch schrieb: > Kann ich mir in dieser Allgemeinheit für einen Prozessor ohne > Hardware-Division nicht vorstellen. Ich ja eigentlich auch nicht, aber da der C166 einen Hardware-Divider auf dem Chip hat, schon :-) Die 20 Takte gelten übrigens für 32/16 Division, bei der der eingebaute Barrelshifter wohl auch seinen Teil dazu beiträgt.
Wenns ganz knapp wird, und nur seltene log Ausgaben sind, könnte man auch den Aufwand an den Leser / Interpreter abschieben und sein eigenes utoa mit fixer Base 16 schreiben. Das wäre dann pro Stelle ca. 1 Und, 4 Shifts nach rechts und eine Addition. Und das Ergebnis ist immer noch recht lesbar.
Kann man auch einfach im Debugger ausmessen lassen. States von Step3 - States von Step2 = States von sprintf. 5616 - 1943 = 3673 States.
m.n. schrieb: > da der C166 einen Hardware-Divider auf dem Chip hat, schon :-) Ja, dafür ist es erklärlich.
Danke an alle! Ich muss gestehen, dass ich ehrlich gesagt nicht an den Debugger bzw. Simulator gedacht habe - das ist natürlich eine komfortable Lösung. Viele Grüße Maax
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.