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
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.
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.
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.
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