mikrocontroller.net

Forum: Compiler & IDEs Stringformatierung Codegrösse


Autor: Manfred Häfner (mhelectronics)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

für die Ausgabe eines float Wertes auf ein LCD wollte ich ursprünglich 
die dtostrf-Funktion nutzen. Die braucht aber allein schon ca. 4kB = 50% 
des flash auf dem Atmega88 !
Zur Abhilfe dann habe ich den float Wert mit 10 multipliziert und in int 
gewandelt, diesen Wert dann mit der itoa-Funktion  zum String gemacht. 
Soweit OK, Codegrösse im Rahmen.
Jetzt möchte ich diesen String noch rechtsbündig formatieren und ein 
Komma vor der letzten Ziffer einfügen (= int-Wert/10). Dazu brauche ich 
die String-Länge. Die eingebaute strlen-Funktion braucht aber ebenfalls 
ca. 3kB = 35% meines Flash. Deshalb habe ich eine eigene Funktion 
geschrieben:

int string_length(char *c, int max_string_size)
  {
  //int i = 0;
  //while(c[i] ; && i < string_size);
  //return i;

  for(int i=0; i < max_string_size; i++)
    if (!c[i])
    return i;

  return 0;
  }

Diese Funktion braucht ebenfalls ca. 3kB ! Egal ob als while- oder 
for-Schleife ! Die weitere Untersuchung ergab daß der große 
Codeverbrauch einzig aus der Zeile " if (!c[i]) " herrührt. Sobald ich 
diese auskommentiere oder in z.B "if (i>5)" ändere brauche ich 3kB 
weniger.
Das Array besteht aus max. 5 Ziffern. Eingebunden sind nur <avr/io.h> 
und <stdlib.h>.

Kann mir jemand sagen warum diese simple Abfrage soviel code verbraucht 
oder wie ich den float Wert (ca. -100.0 bis +300.0) sparsamer in einen 
rechtsbündigen String wandeln kann.

Gruß Manfred

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vergiss Float. Nimm Festkommaarithmetik.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manfred Häfner wrote:
> Hallo Leute,
>
> für die Ausgabe eines float Wertes auf ein LCD wollte ich ursprünglich
> die dtostrf-Funktion nutzen. Die braucht aber allein schon ca. 4kB = 50%
> des flash auf dem Atmega88 !
Du solltest vielleicht, wenn Du schon absolut nicht auf floats 
verzichten kannst, die Linkeroption -lm hinzufügen.

Für die meisten Fälle in der Praxis sind Gleitkommaberechnungen aber 
tatsächlich überflüssig!

> int string_length(char *c, int max_string_size)
>   {
>   //int i = 0;
>   //while(c[i] ; && i < string_size);
>   //return i;
>
>   for(int i=0; i < max_string_size; i++)
>     if (!c[i])
>     return i;
>
>   return 0;
>   }
>
> Diese Funktion braucht ebenfalls ca. 3kB !
Diese Funktion braucht, so wie sie hier steht, nie im Leben 3 KiB!

Autor: SoLaLa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmmm...
wenn das c[i] und string_length sonst nirgendwo benutzt wird, dann 
optimiert der Compiler doch bestimmt die ganze Bibliothek weg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:

>> Diese Funktion braucht ebenfalls ca. 3kB !
> Diese Funktion braucht, so wie sie hier steht, nie im Leben 3 KiB!

Genauso wie ich nicht glaube, dass die Original strlen 3 KiB verbraucht. 
Da ist irgendetwas anderes faul. Irgendwas kann wegoptimiert werden, 
wenn der Vergleich rausfällt. Und als Folge davon werden wiederrum 
andere Teile wegoptimiert, sodass unterm Strich ein Wenigerverbrauch von 
3KB rauskommt.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:
> Diese Funktion braucht, so wie sie hier steht, nie im Leben 3 KiB!

Warscheinlich wieder ein Fall für den "-lm" Superman.

Hast Du nicht auch 264 Byte SRAM verloren?


Peter

Autor: Manfred Häfner (mhelectronics)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den schnellen Feedback .....

1. Die Funktion verbraucht nicht 256 Byte SRAM, nur etwa 7-10 Byte, 
entsprechend der Stringlänge.

2. ist die Funktion so wie beschrieben, belegt das gesamte Programm im 
flash ca. 4.3 kB, nach deaktivieren nur der Zeile " if (!c[i]) " nur 
noch ca. 1.2 kB. Das Abscannen des nur ca. 6 Felder langen array belegt 
also eindeutig ca. 3 kB im flash. (mit mehreren Optimierungsgraden 
getestet, Unterschiede nur unwesentlich!). Bei Verwendung der 
strlen-funktion dasselbe.

3. Das array c[i] wird natürlich bei der itoa() funktion beschrieben und 
bei der LCD ausgabe mit lcd_string() gelesen, sonst wird es nirgends 
benutzt, die string_lenght() wird sonst nicht benutzt.

4. Festkommaarithmetik wende ich schon an, hat mit der sting_length() 
nix zu tun. Der Umbau des Programms von float zu int hat zuvor etwa 800 
byte gebracht.

5. wo muß die linker-option " -lm " hin? in das makefile oder? (bin 
Anfänger mit GCC :-).
Nutzt es was, wenn ich den gesamten Code mal hier anhänge?

Gruß Manfred

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das Abscannen des nur ca. 6 Felder langen array belegt
> also eindeutig ca. 3 kB im flash.
Ich denke eher, der Compiler sieht, dass immer der gleiche Wert
zurückgegeben wird, und kann was anderes rausschmeißen.
Schau doch mal das Assembler-File an, dort siehst du, wer dir den 
Speicher verbrät.

> Nutzt es was, wenn ich den gesamten Code mal hier anhänge?
Ja.
Als Dateianhang mit der Endung .c, dann wird er hübsch formatiert ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.