mikrocontroller.net

Forum: Compiler & IDEs Minimalbeispiel zur Darstellung effizienter Schleifen


Autor: essence (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nabend,

ich versuche mich gerade an einem Minimalbeispiel:
#include <avr/io.h>
int main(void) {
  uint8_t i, n;
  for (i=0; i<17; i++) {
    n++;
  }
}

Daraus wird allerdings im .lss:
int main(void)
{
  b4:  80 e0         ldi  r24, 0x00  ; 0
  b6:  90 e0         ldi  r25, 0x00  ; 0
  b8:  08 95         ret

000000ba <_exit>:
  ba:  f8 94         cli

000000bc <__stop_program>:
  bc:  ff cf         rjmp  .-2        ; 0xbc <__stop_program>

Ich nehme an, dass durch das Makefile irgendwelche Optionen aktiviert 
werden, die die Schleife eliminieren.
Könnte das jemand bei sich testen oder mir ein Makefile mit 
funktionierenden Optionen zukommen lassen?

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, Schleife ist sinnlos -> weg damit. Macht quasi jeder optimierende 
Übersetzer so.

Für GCC: Option -O0 (Oh-Null).

Autor: essence (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das habe ich mir fast gedacht. Danke.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es scheint mir aber irgendwie sinnfrei zu sein, zu untersuchen, wie eine 
effiziente Umsetzung einer Schleife durch den Compiler aussieht, wenn 
man dabei Optimierungen ausschaltet.
Der Beispielcode ist natürlich ähnlich sinnfrei, da einerseits n einen 
undefinierten Wert hat, andererseits ein 17maliges Inkrementieren von n 
das gleiche ist wie n += 17. Dazu kommt dann noch, daß weder i noch n 
für irgendwas verwendet werden, also optimiert der Compiler kurzerhand 
einfach alles komplett weg. So gesehen gäbe es keine Möglichkeit, die 
Schleife noch effizienter umzusetzen, als es der Compiler getan hat. ;-)

Autor: Uwe ... (uwegw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch effizienter (allerdings nicht mehr standardkonform, GCC macht es 
aber trotzdem) wird es, wenn du den Rückgabetyp von main() auf void 
änderst. Dann hast du eine Funktion, die nichts macht, was irgendwas 
außerhalb von ihr bewirkt, und die nichts zurückgibt. Ergebnis der 
Optimierung:
ret
Effizienter geht es kaum noch, man könnte nur noch inlinen und sämtliche 
Aufrufe von main() rauschmeißen [was aber wohl kein Compiler machen 
würde, weil ne leere Main ja nicht gerade üblich ist]... Und wenn main() 
dann also nie aufgerufen wird, dann könnte man auch den Startup-Code 
weglassen... somit bleibt nicht übrig...

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1.) Meckert der Compiler nicht über die fehlende return-Anweisung?

2.) Bei z.B. einem return n; dürfte der Compiler die Variable nicht so 
einfach wegoptimieren? Sonst zieht er sich ja den Rückgabewert unter den 
Füßen weg ;o)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 2.) Bei z.B. einem return n; dürfte der Compiler die Variable nicht so
> einfach wegoptimieren? Sonst zieht er sich ja den Rückgabewert unter den
> Füßen weg ;o)

Er muß in diesen Zeilen
 b4:  80 e0         ldi  r24, 0x00  ; 0
  b6:  90 e0         ldi  r25, 0x00  ; 0

einfach die 0 durch den Wert, den n nach der Schleife hätte, ersetzen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:

> Er muß in diesen Zeilen
> einfach die 0 durch den Wert, den n nach der Schleife hätte, ersetzen.

Da n einen undefinierten Anfangswert hat, ist 0 ein absolut korrekter
return-Wert. ;-)

Autor: jozi59 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zumal n auch überhaupt nicht als return value verwendet wird. Es wird 
nämlich überhaupt kein return value angegeben. :-)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Er muß in diesen Zeilen einfach die 0 durch den Wert, den n nach der
>> Schleife hätte, ersetzen.
>
> Da n einen undefinierten Anfangswert hat, ist 0 ein absolut korrekter
> return-Wert. ;-)

Allerdings. Das wollte ich eigentlich nicht weiter ausführen. Rein aus 
Interesse habe ich aber mal geschaut, was der Compiler denn tatsächlich 
daraus macht, und er entscheidet sich dafür, n wie mit 0 initialisiert 
zu behandeln, schreibt also einen Rückgabewert von 17 in die Register.

@jozi59:

> Zumal n auch überhaupt nicht als return value verwendet wird.

Vielleicht liest du besser nochmal nach, worauf ich geantwortet hatte.

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.