Forum: Compiler & IDEs Optimierungslevel bei AVRStudio4 ?


von Jan M. (joachim)


Lesenswert?

Hallo Leute,
hab als µc-Anfänger zur Nutzung von AVRStudio4 mal folgende Frage:
Man kann, um die Codegröße zu optimieren, ja bei AVRSudio4 verschiedene
Level einstellen.
z.B. 00, -01, -02 usw. Kann man die in jedem Falle nutzen, um die
Codegröße zu optimieren, oder kann dies auch zu Verwurstelungen führen,
so das ein Programm, was im 0-Level läuft, z.B. im Level
-03  nicht mehr richtig funktioniert ? Ich möchte diesbezüglich gern
wissen, ob es Sinn macht, diese Optimierungsstufen einzusetzen oder
besser nicht.

Besten Dank entsprechende  Tipps !!

Mit freundlichen Grüßen
J.M.

von Fritz G. (fritzg)


Lesenswert?

Zum kleinermachen kannst du nur -Os nehmen.
Besonders -O2 erzeugt gern größeren Code, der aber schneller ist.

Funktionieren wird das Programm auch mit allen Optimierungsstufen
gleich, nur halt entsprechend schneller (falls keine Bugs drin sind).
Manche böse Bugs treten aber z.B. erst bei -O2 zutage.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> ...so das ein Programm, was im 0-Level läuft, z.B. im Level -03
> nicht mehr richtig funktioniert?

Ja, natürlich.  Es gibt hinreichend Beispiele für ,,vergurkte''
Programme, die mit -O0 dann trotzdem noch funktionieren, obwohl sie
eigentlich kaputt sind.  Prominentestes Beispiel dafür sind natürlich
vergessene volatile-Qualifier an Variablen, die in verschiedenen
Codethreads (also z. B. main und Interrupt) wechselseitig benutzt
werden.

Andererseits kann bei zeitkritischen Dingen genau das Gegenteil
eintreten: diese funktionieren nur mit mindestens -O1 vernünftig, weil
der mit -O0 generierte Code so aufgeblasen und umständlich ist (eben
eine geradlinige 1:1-Umsetzung des hingeschriebenen C-Codes), dass
alle Messen für eine vernünftige Ausführungszeit gesungen sind.

Meistens ist -Os das ,Optimum', bei dem sowohl geringe Codegröße als
auch kurze Ausführungszeiten erreicht werden.  Allerdings haben wir
mal in einem Projekt Zeitwerte gemessen, -O3 hat bei ca. 10 % größerem
Code dann auch nochmal ca. 10 % Zeiteinsparung im kritischen Pfad
gebracht.  Da man letztlich den gesamten ROM des gewählten Prozessors
kaufen muss und keinen Bonus dafür erhält, wenn man einen Teil des
ROMs nicht benutzt, kann das also am Ende schon eine Option sein.

von Freakazoid (Gast)


Lesenswert?

Hi,

also ich hab mit O0 schlechte Erfahrungen. Teilweise fehlerhafter Code.
Keine Ahnung, ob das behoben wurde:
http://www.mikrocontroller.net/forum/read-4-243641.html#265139

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> also ich hab mit O0 schlechte Erfahrungen. Teilweise fehlerhafter
> Code.

Das ist eine Behauptung, deren Beweis du schuldig geblieben bist.

von Fritz G. (fritzg)


Lesenswert?

> also ich hab mit O0 schlechte Erfahrungen. Teilweise fehlerhafter
> Code.


Oja, ich hab auch schon viele Compilerfehler entdeckt!
Nach einigem debuggen kam immer wieder raus, dass der Fehler in der
Funktion read_keyboard() des Editors steckte! :-)

SCNR

von Freakazoid (Gast)


Lesenswert?

Okay. Witzig. Ich hab mal ein wenig gebuddelt. Hier mal ein Teil aus der
S65-Library (um die ging es bei meinem Verweiß):

O0:
  // setup SPI Interface
  SPCR = _BV(MSTR) | _BV(SPE) | _BV(SPR0);
     272:  81 e5         ldi  r24, 0x51  ; 81
     274:  80 93 2d 00   sts  0x002D, r24
O3:
  // setup SPI Interface
  SPCR = _BV(MSTR) | _BV(SPE) | _BV(SPR0);
 188:  81 e5         ldi  r24, 0x51  ; 81
 18a:  8d b9         out  0x0d, r24  ; 13

Fällts auf? BTW: Die GCC-Entwickler empfehlen selbst O0 nicht
einzusetzen. Den Beitrag werd ich auch mal suchen.

Grüße,
Freakazoid

von Karl H. (kbuchegg)


Lesenswert?

Und, was ist daran falsch :-)

Der 'Port' ist auf 2 Wegen erreichbar.
Entweder wird er als I/O Port angesprochen, dann
liegt er auf I/O Port 0D. Oder aber er wird
memory mapped angesprochen, dann liegt er auf Adresse 2D.

von Freakazoid (Gast)


Lesenswert?

Ist er das wirklich? Bei mir ging es nicht ;-( Es kann natürlich
trotzdem sein, daß mein Fehler noch woanders lag (siehe Tip von Fritz
Ganter). Ich denke schon, daß der GCC da okay ist (hab mich wohl oben
ein wenig zu undeutlich ausgedrückt).
Fakt ist aber, daß das Programm erst mit O2 lief. Es gab keine
Zeitschleifen oder sonstwie optimierungsabhängige Teile.

Das mit dem 2-Wege-Port les ich mal nach.

Übrigens:
In einem anderen Forum wurde das so hingenommen. Ich finde es gut, daß
mich mal jemand auf die '2 Wege' aufmerksam macht. Hätte man zwar
auch selbst vermuten können, aber ich hab wohl ein wenig zu schnell die
Flinte ins Korn geworfen.
Wenn dem wirklich so ist, ist mein Vertrauen wieder da.
Dachte schon ich müßte die ganze Zeit in Assembler programmieren ;-)

Grüße,
AK

von Stefan K. (_sk_)


Lesenswert?

Sehe auch kein Problem in dem O0-Code. sts erzeugt größeren und
langsameren Code als out, klar: nicht optimiert ...

Statt Dich still zu ärgern, melde doch beim nächsten Mal den "Bug"
auf sourceforge. Entweder es war wirklich ein Bug: dann haben alle was
davon, oder es war keiner: dann bekommst Du dort sicher die
kompetenteste Antwort.

Gruß, Stefan

von Freakazoid (Gast)


Lesenswert?

Naja. Andersrum hätt ich auch mal besser debuggen können. Stattdessen
hab ich lieber wieder auf Assembler gesetzt. Naja. War letztes Jahr.
Jetzt mach ich ein paar Sachen besser.

von Freakazoid (Gast)


Lesenswert?

Und hier die '5-Wege-Adressierung:

...
The five different addressing modes for the Data memory cover: Direct,
Indirect with
Displacement, Indirect, Indirect with Pre-decrement, and Indirect with
Post-increment. In
the Register File, registers R26 to R31 feature the indirect addressing
pointer registers.
...

...
The 32 general purpose working registers, 64 I/O Registers, and the 64
bytes of internal
data SRAM in the ATtiny13 are all accessible through all these
addressing modes. The
Register File is described in “General Purpose Register File” on page
8.
...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

>> Der 'Port' ist auf 2 Wegen erreichbar.

> Ist er das wirklich?

Die MMIO-Zugriffe (memory-mapped IO) sind der einzige Weg, mit dem es
garantiert ist, dass man alle IO-Ports erreichen kann.  Je nach
Prozessor ist nur ein Teil davon (nämlich die unteren 64 -- von
vielleicht insgesamt 224 beim ATmega1280) via IN und OUT erreichbar,
und wiederum davon kann nur die Hälfte davon (die ersten 32) auch mit
SBI und CBI manipuliert werden.

Daher arbeitet der Compiler intern erst einmal einheitlich mit MMIO.
Der Optimierer erkennt dann daraus die Fälle (statische Portadressen
im passenden Bereich, ggf. statische Bit-Nummern für Manipulation), in
denen man statt des umständlichen MMIO mit kürzeren Befehlssequenzen
auskommt.

von Unbekannter (Gast)


Lesenswert?

Es ist immer wieder lustig, wieviele meinen der Compiler würde Müll
machen. Dabei kann man ganz locker davon ausgehen, dass der Fehler in
99,99% der Fälle beim Compiler-Benutzer liegt und nicht beim Compiler.

Der durchschnittliche Programmierer schreibt nur durschnittlichen Code
der den Compiler auch nur vor durchschnittlichen Optiemierungsaufgaben
stellt.

Man muss schon ziemlich raffinierte Konstrukte bauen, um Compiler-Bugs
zu triggern. Ist ja auch logisch: Das ganze Null-Acht-Fünfzehn-Zeug
kompiliert so ein Compiler in vielen Installationen tagtäglich völlig
problemlos. Da würden die trivialen Compiler-Fehler sofort auffallen.

Im übrigen: Ein Programm das nur bei bestimmten
Optimierungseinstellungen funktioniert ist definitiv fehlerhaft.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Kommt hinzu, dass wahrscheinlich 99 % der GCC-Bugs eher in einem
"Internal Compiler Error" (ICE) enden, der zu einem Abbruch führt,
statt einfach stillschweigend fehlerhaften Code zu generieren.

von Karl H. (kbuchegg)


Lesenswert?

Natürlich ist ein Compiler auch nur ein Program und enthält
Fehler. Allerdings kann man bei Compilern die etwas länger
am Markt vorhanden sind, davon ausgehen, daß Fehler in den
eher etwas 'esoterischen' Bereichen der Sprache zu finden
sind. Bei den meisten C++ Compilern ist das der Bereich
Metaprogrammierung und Templates. So was einfaches wie
eine Zuweisung (und sei sie noch so kompliziert in Assembler
umzusetzen) kriegt heutzutage jeder Compiler so zu sagen
im Schlaf und mit links hin.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.