CPU Cycles printf bzw sprintf

Gast #3726167
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
Gast
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?
Gast
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.
Gast
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.
Gast
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).
Moderator Persönliche Seite
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.
Gast
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.
Gast
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.