www.mikrocontroller.net

Forum: Compiler & IDEs Seltsames Compilerergebnis


Autor: JarJar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
bin hier grad über eine merkwürdige Sache gestolpert. Folgendes simple
Programm:

#include <avr/io.h>

int main(void)
{
    DDRB = 0xff;
    while(1)
    {
        PORTB=0x00;
        PORTB=0xff;;
    }
}

Erzeugt bei Opt = -O2 folgenden ASM Code

    while(1)
    {
        PORTB=0x00;
  9a:  18 ba         out  0x18, r1  ; 24
        PORTB=0xff;;
  9c:  88 bb         out  0x18, r24  ; 24
  9e:  18 ba         out  0x18, r1  ; 24
  a0:  88 bb         out  0x18, r24  ; 24
  a2:  fb cf         rjmp  .-10       ; 0x9a

D.h. er verdoppelt das ganze was auch am Oszi zu sehen ist. Bei Opt =
-O1 oder -Os macht er es richtig.

    while(1)
    {
        PORTB=0x00;
  9a:  18 ba         out  0x18, r1  ; 24
        PORTB=0xff;;
  9c:  88 bb         out  0x18, r24  ; 24
  9e:  fd cf         rjmp  .-6        ; 0x9a


Will jetzt nicht kleinlich sein, bin aber neugierig warum...

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist doch völlig korrekt. -O2 optimiert auf Laufzeit, -Os auf Platz.

Google mal nach "loop unrolling".

Autor: JarJar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, danke. Wieder was gelernt :)

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, korrekt ist es schon, aber den Inhalt einer while(1)-Schleife
einfach zu verdoppeln erscheint mir etwas... beliebig.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird schneller dadurch, weil ein Sprung eingespart wird. Dass
Microcontroller so bisweilen stolpernde Takte erzeugen - je nun, das
ist GCC sowas von egal. Probier das mal mit einer 100-er Schleife, da
wird dann evtl. der Inhalt verdoppelt aber die Anzahl Durchläufe
halbiert.

Von Bedeutung ist das eher bei Standardprozessoren. Denn dort kann
diese Optimierung Fliesskomma-Rechenoperationen ein Vielfaches
beschleunigen. Deshalb steckt das im GCC drin. Beim AVR ist das ein nur
selten erwünschter Nebeneffekt - den man mit irgendeinem
-fno-loop-unrolling oder so auch abschalten kann.

Generell ergibt alles andere als -Os beim GCC/AVR wenig Sinn.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe auch schon erlebt, daß der Compiler mit -Os nicht nur
langsameren, sondern auch größeren Code als mit -O3 produziert hat,
weil er bei -Os scheinbar kein Inlining macht. Makros kann ich nicht
einsetzen, da ich mit C++ arbeite und es sich um eine Memberfunktion
handelt. Allerdings kann man Funktionen mit
__attribute__((always_inline)) ausstatten, was genau das tut, was man
erwarten würde. So kann meine C++-Library auch mit -Os optimal
übersetzt werden. Inline-Funktionen sind auch sauberer und sicherer als
Makros.

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

Bewertung
0 lesenswert
nicht lesenswert
Nun, wenn du ihm eine Funktion als inline deklarierst, dann macht er
das durchaus auch bei -Os, aber eben nicht immer.  Der Compiler
versucht eine Abschätzung zu machen, ob das inlining Sinn hat.  Es
leuchtet ein, dass er sich bei dieser Abschätzung auch mal vertun
kann.

Was allerdings bei -Os (und wohl auch bei -O2, im Gegensatz zu -O3)
wirklich nicht passiert ist, dass der Compiler selbst Funktionen als
inline-Code übernimmt.

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.