www.mikrocontroller.net

Forum: Compiler & IDEs GCC inlined die ganze Zeit meine Funktionen.


Autor: Matthias Larisch (matze88)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe gerade ein Problem mit meinem GCC, Version ist das neuste 
WinAVR (vom Juni).
Und zwar meint er trotz Optimierung -Os häufig Funktionen inlinen zu 
müssen, auch wenn das aus meiner Sicht völlig schwachsinnig / 
verschwenderisch ist. Gibt es ein Keyword, um dem Compiler zu sagen, 
dass diese Funktion immer explizit aufgerufen werden soll? Ich kann ja 
schlecht für jede Funktion ein eigenes C-File machen :-)

Ein Beispielcode:
char pgmInitSirfMode[] PROGMEM = "\x1b" "$PSRF100,0,38400,8,1,0*3C\r\n";

void gps_enable (void)
{
  PRR &= ~(1 << PRUSART0);
  UBRR0 = GPS_UBRRVAL;
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
  FETPORT &= ~(1 << GPS_FET);
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  gps_transmit_p(pgmInitSirfMode);
}

void gps_transmit (uint8_t byte)
{
  while (! (UCSR0A & (1 << UDRE0)));
  UDR0 = byte;
}

void gps_transmit_p (PGM_P address)
{
  uint8_t count = pgm_read_byte(address++);
  while(count--)
  {
    gps_transmit(pgm_read_byte(address++));
  }
}

Das generierte Listing für den Abschnitt ist im Anhang.
Kurz beschrieben: Er inlined einmal die gps_transmit_p und dortdrin auch 
noch den gps_transmit Aufruf. Somit vergeudet der liebe GCC alleine an 
dieser Stelle etliche Bytes Flash, ohne gezählt zu haben sind das 
sicherlich ~30.

Das gleiche Problem hatte ich mit meiner Init() Funktion, welche zu 
Beginn der Main aufgerufen wird. Das Problem habe ich gelöst, indem ich 
sie einfach als inline deklariert habe, sodass er sie nicht nochmal als 
aufrufbare Funktion ins Flash packt. Das ist aber eher ein work-around 
und geht nicht immer... Warum "optimiert" er denn bei -Os nicht wirklich 
auf kleinen Code? In diesem Fall hier wäre der Geschwindigkeitsverlust 
durch den call sehr marginal im Vergleich zur sowieso benötigten 
Ausführungszeit...

Was mache ich falsch? :-)

cu
Matze

Autor: Freizeitbastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Matze

ich fange gerade erst an mit WinAVR. Im Allgemein lässt sich für C aber 
sagen: Wenn Du die Funktionen in getrennte Quelldateien packst wird der 
Compiler nicht mehr inlinen.

Ob das Inlinen hier wirklich schlecht ist, wäre ich mir nicht so sicher. 
Da können die Experten sicherlich etwas zu sagen.

Gruß, Peter

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

Bewertung
0 lesenswert
nicht lesenswert
Versuch es einfach mal mit
__attribute__((noinline))
in der Funktionsdefinition.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-fno-inline
-fno-inline-small-functions

Autor: Matthias Larisch (matze88)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahh, sehr gut :-) Habt vielen Dank für eure Antworten. Ich verstehe zwar 
noch nicht so ganz, warum der Compiler da meiner Meinung nach suboptimal 
arbeitet, aber der kann ja auch eigentlich nicht wissen, wie die 
Laufzeit der Funktion dann wirklich ist. Ich freu mich jetzt jedenfalls 
über gesparte 150 Bytes Flash :-)

cu
Matze

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich verstehe zwar
> noch nicht so ganz, warum der Compiler da meiner Meinung nach suboptimal
> arbeitet, aber der kann ja auch eigentlich nicht wissen, wie die
> Laufzeit der Funktion dann wirklich ist.

Naja, deine Funktionen sind ja sehr kurz, und eigentlich ideale 
Kandidaten fürs Inlining.
Scheinbar gefällt dem GCC das inlining hier sogar so gut, dass er es 
trotz -Os macht (Gibts sicher einen Parameter mit dem man das 
feineinstellen kann)

Und nachdem die Funktionen nicht als "static" deklariert sind, muss er 
sie halt ein zweites mal, für den Aufruf aus anderen C-Files heraus, in 
das Object-File compilieren.

Edit:
 `-finline-limit=N' Scheint die richtige GCC-Stellschraube zu sein...

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.