Forum: Mikrocontroller und Digitale Elektronik CPU Cycles printf bzw sprintf


von Maax (Gast)


Lesenswert?

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

von Cyblord -. (cyblord)


Lesenswert?

Na Bub dann mess halt. Portpin setzen, printf aufrufen, Portpin löschen. 
Messen, Rechnen, Fertig. Nichts geht schneller.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Maax (Gast)


Lesenswert?

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.

von Maax (Gast)


Lesenswert?

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

von Cyblord -. (cyblord)


Lesenswert?

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?

von Maax (Gast)


Lesenswert?

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.

von Cyblord -. (cyblord)


Lesenswert?

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.

von Max H. (hartl192)


Lesenswert?

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
von Maax (Gast)


Lesenswert?

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.

von Cyblord -. (cyblord)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von m.n. (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von m.n. (Gast)


Lesenswert?

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.

von Philip P. (nosuchnick)


Lesenswert?

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.

von Helmut L. (helmi1)


Angehängte Dateien:

Lesenswert?

Kann man auch einfach im Debugger ausmessen lassen.

States von Step3 - States von Step2 = States von sprintf.
           5616  -            1943  = 3673 States.

von Helmut L. (helmi1)


Angehängte Dateien:

Lesenswert?

Hier noch Step3

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

m.n. schrieb:
> da der C166 einen Hardware-Divider auf dem Chip hat, schon :-)

Ja, dafür ist es erklärlich.

von Maax (Gast)


Lesenswert?

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

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Uiiiiiiiiiiiuiuiuiuui ..... µVision2 :-)

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
Noch kein Account? Hier anmelden.