mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR-Studio - Code Größe anzeigen


Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

mal 'ne blöde Frage: Gibt es im AVR-Studio eine elegante Möglichkeit, 
sich die Größe des vom GCC erzeugten ASM-Codes anzeigen zu lassen, außer 
der Ausgabe nach dem Kompilieren?

Mir geht das ständige "Kompilieren und Ergebnis vergleichen" auf den 
Zeiger und ich versuche noch ein paar Byte Flashspeicher aus dem 
Kompilat zu quetschen.

Sonst noch irgendwelche guten Ratschläge (außer die, die im Artikel 
Code-Optimierung bzw. im AVR-Datenblatt stehen), wo man nochmal nach ein 
wenig Speicher auf die Suche gehen kann? Was verbraucht i.d.R. viel 
Flash-Speicher, was nicht?

Und ja, die Optimierung steht auf -Os! ;)

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Klarstellung, ich hätte gerne eine Anzeige
a+b; // z.B. 2 Byte
a*b; // z.B. 150 Byte
oder so ähnlich...

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

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Hallo,
>
> mal 'ne blöde Frage: Gibt es im AVR-Studio eine elegante Möglichkeit,
> sich die Größe des vom GCC erzeugten ASM-Codes anzeigen zu lassen, außer
> der Ausgabe nach dem Kompilieren?
>
> Mir geht das ständige "Kompilieren und Ergebnis vergleichen" auf den
> Zeiger und ich versuche noch ein paar Byte Flashspeicher aus dem
> Kompilat zu quetschen.

Ähm.
Zettel daneben hinlegen und die Zahl notieren.
Dann weiß man sofort durch Vergleichen obs mehr oder weniger wird.

> Sonst noch irgendwelche guten Ratschläge (außer die, die im Artikel
> Code-Optimierung

Die vergiss gleich mal wieder. 80% der dort gegebenen Ratschläge stammen 
aus alten Zeiten und sind schon lange nicht mehr aktuell. Wahrscheinlich 
waren die überhaupt nie aktuell.

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

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Zur Klarstellung, ich hätte gerne eine Anzeige
>
> a+b; // z.B. 2 Byte
> a*b; // z.B. 150 Byte
> 
> oder so ähnlich...

Die gibt es nicht. Denn je nach Zusammenhang kann der Compiler die 
Operationen hin und herschieben und wenns ganz toll kommt, fallen sie 
komplett raus.

Mann kann den Assembler Output studieren um zu sehen, wo der Compiler 
dem Gefühl nach eher umständlich übersetzt hat und sich dann auf die 
Suche begeben, welches C-Faktum man übersehen bzw. übersehen hat und so 
den Compiler am besseren Optimieren gehindert hat.

Aber normalerweise bringt es mehr, wenn man auf Hochsprachenebene 
anfängt und sich die benutzten Verfahren genauer überlegt.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ähm.
> Zettel daneben hinlegen und die Zahl notieren.
> Dann weiß man sofort durch Vergleichen obs mehr oder weniger wird.

Das meinte ich doch. Genau das mach ich. Durch Abhängigkeiten etc. ist 
es aber nicht gerade effektiv, da die Änderungen am Code teilweise 
umfangreich ausfallen und die Erkenntnis/Zeit gering bleibt...

Eine Ausgabe, in der Mann sieht, welcher C-Code welchen ASM Code erzeugt 
hat, wie man ihn ja manchmal auch in Tutorials & Threads findet, gibt es 
also beim GCC nicht?

Damit ließen sich die problematischen Stellen schneller finden und 
gezielt bearbeiten.

> Die vergiss gleich mal wieder. 80% der dort gegebenen Ratschläge stammen
> aus alten Zeiten und sind schon lange nicht mehr aktuell. Wahrscheinlich
> waren die überhaupt nie aktuell.

Da ich mich bereits ein wenig eingelesen habe und dies hier im Forum 
bereits mehrfach Thema war, ist mir das nicht unbekannt gewesen.
Wenn die Tipps aber so kontraproduktiv und evtl. falsch sind, warum 
existiert der Artikel noch? Und: Gibt es Artikel mit dem gleichen Thema 
aber sinnvollen Ratschlägen?

Ein paar Fragen, die ich mir gerade stelle:
- Erzeugt die Verwendung von Bitfeldern zwar schnelleren, aber größeren 
Code? Oder andersrum?
- Wie geht man am geschicktesten mit globalen Variablen um, wenn man 
speicher sparen will?
- Welche Zugriffe erzeugen viel Code, welche nicht?
- Dito für Operanden, C-Strukturen (Funktionen, Auslagern in externe 
Dateien, ...)?
- Ab wie vielen Zugriffen aus dem Programm ist das Auslagern in eine 
Funktion sinnvoll?

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Mann kann den Assembler Output studieren um zu sehen, wo der Compiler
> dem Gefühl nach eher umständlich übersetzt hat und sich dann auf die
> Suche begeben, welches C-Faktum man übersehen bzw. übersehen hat und so
> den Compiler am besseren Optimieren gehindert hat.

Frau auch? ;)

Im Ernst: Wo steht denn der Assembler-Code? Ich finde keine ASM-Datei in 
meinem Output-Folder.

Ich muss gestehen, bisher hat mich ASM-Code wenig interessiert. Ich 
müsste also selbst den Code auseinanderdröseln und raten wo was getan 
wird? Kann man sowas als ASM-Anfänger überhaupt oder müsste man dafür 
das Thema stark vertiefen?

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

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:

> Eine Ausgabe, in der Mann sieht, welcher C-Code welchen ASM Code erzeugt
> hat, wie man ihn ja manchmal auch in Tutorials & Threads findet, gibt es
> also beim GCC nicht?

Natürlich.
Man kann vom Compiler selbstverständlich auch das Assembler Listing 
anfordern ....
>
> Damit ließen sich die problematischen Stellen schneller finden und
> gezielt bearbeiten.

.... nur sagt mir meine Kristallkugel jetzt schon, dass du damit nicht 
glücklich werden wirst :-)


> Wenn die Tipps aber so kontraproduktiv und evtl. falsch sind, warum
> existiert der Artikel noch?

Gute Frage

> Und: Gibt es Artikel mit dem gleichen Thema
> aber sinnvollen Ratschlägen?

AFAIK nein.

> Ein paar Fragen, die ich mir gerade stelle:
> - Erzeugt die Verwendung von Bitfeldern zwar schnelleren, aber größeren
> Code? Oder andersrum?

Es erzeugt genau den gleichen Code, den du selber auch mittels

    Variable |= ( 1 << Bitnummer );

generieren würdest.
Durch das Bitfeld versteckst du lediglich das Shiften und Verodern, also 
die eigentliche arbeitende Ebene, vor dem geneigten Programmleser. Aber 
zaubern können auch Bitfelder nicht.

> - Wie geht man am geschicktesten mit globalen Variablen um, wenn man
> speicher sparen will?

Gar nicht.
Wenn du 60 Bytes globale Variablen brauchst, dann brauchst du 60 Bytes 
globale Variablen. Da führt kein Weg drann vorbei. Man kann sich 
höchstens fragen, ob tatsächlich alle Variablen global sein müssen, oder 
ob einzelne Variablen nicht besser funktionslokal sein sollten. 
Allerdings: Variable ist Variable. Irgendwo muss sie existieren. Manche 
Variablen kann der COmpiler wegoptimieren, aber das ist dann eher 
selten.

> - Welche Zugriffe erzeugen viel Code, welche nicht?

kann man so pauschal nicht sagen

> - Dito für Operanden, C-Strukturen (Funktionen, Auslagern in externe
> Dateien, ...)?

Auch das kann man so pauschal nicht sagen

> - Ab wie vielen Zugriffen aus dem Programm ist das Auslagern in eine
> Funktion sinnvoll?

Das hat damit nicht sehr viel zu tun. Eigene Funktionen können schon 
rein aus Übersichtsgründen bzw. aus Gründen der Codestrukturierung 
sinnvoll sein.

Wenn du ein wenig Code zeigst, dann könnten die hier ein paar Leute 
helfen nach Flaschenhälsen zu suchen.

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

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:

> Im Ernst: Wo steht denn der Assembler-Code? Ich finde keine ASM-Datei in
> meinem Output-Folder.

Im AVR-Studio in den Project Options das Listfile einschalten.
Im Output Folder gibt es dann eine *.lss Datei

> müsste also selbst den Code auseinanderdröseln und raten wo was getan
> wird? Kann man sowas als ASM-Anfänger überhaupt oder müsste man dafür
> das Thema stark vertiefen?

Siehs dir an

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab schon 5% gefunden, mit dem Compiler-Schalter:
-fno-inline-small-functions

Ich probier jetzt noch ein paar andere Schalter aus, liefert evtl. schon 
genug Speicher. Wusste nicht, dass es da noch Möglichkeiten gibt, bin 
gerade drüber gestolpert.... Hätte vielleicht noch Suchen müssen.

Danke Dir KH! Muss wirklich sagen, dass ich Deine Hilfe nicht zum ersten 
Mal echt zu schätzen weiß. Bist ein Guter! ;)

Karl heinz Buchegger schrieb:
>> Wenn die Tipps aber so kontraproduktiv und evtl. falsch sind, warum
>> existiert der Artikel noch?
>
> Gute Frage
>
>> Und: Gibt es Artikel mit dem gleichen Thema
>> aber sinnvollen Ratschlägen?
>
> AFAIK nein.

Wenn das jemand ändern kann, dann doch Ihr?
Für 1. würde ich eine Löschung oder eine deutliche Warnung am Anfang 
vorschlagen.
Für 2. ein Artikel anlegen, indem jeder mal seine Erfahrungen und 
eigenen kleinen Tests eintragen kann?
Ein Warn

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

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:

>>> Und: Gibt es Artikel mit dem gleichen Thema
>>> aber sinnvollen Ratschlägen?
>>
>> AFAIK nein.
>
> Wenn das jemand ändern kann, dann doch Ihr?

Ja.
Das Problem ist: Das ist ein zweischenidiges Schwert. Es kommt oft auf 
die genauen Umstände an, was konkret funktioniert und was nicht. Und mit 
der nächsten Compilerrelease kann sich vieles ändern.

Ich würde mal sagen:
Die richtigen Datentypen sind wichtig!
Auf einem PC ist das einfach. Da ist einfach alles ein int, ausser man 
hat sehr große Zahlen, dann wirds ein long.
Auf einem AVR ist aber int teuer. Wenn Zahlen nicht größer als 128 
werden können, dann auf jeden Fall int8_t. Wenn die Zahl kein Vorzeichen 
haben kann, dann auf jeden Fall uint8_t benutzen! Alleine durch einen 
unachtsam eingestreuten int kann man sich eine Menge Code aufzwirbeln, 
der sofort verschwindet, wenn man bemerkt, dass es ein uint8_t auch 
getan hätte.

Der GCC hat zwar manchmal so seine Schwierigkeiten, aus der von C 
geforderten int-Rechnerei auf uint8_t abzuspecken, aber generell macht 
er einen guten Job, wenn es um Optimierung geht. D.h. das Hauptaugenmerk 
sollte auf algorithmischer Ebene liegen und nicht auf Kleinvieh. Darum 
kümmert sich der GCC selber ausreichend gut.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider keine Steigerung mehr durch Compiler-Schalter erreicht.
Der eine hat ganz schön draufgehauen.

Gibt es da Verdächtige bei den standardmäßigen aktivieren Schaltern?

Bei mir waren das:
-fshort-enums
-fpack-struct
-funsigned-bitfields
-funsigned-char
-std=gnu99
-gdwarf-2
-Wall

Die Reihenfolge ist ja (hoffentlich) egal, oder?

Aber ein Blick in die lss-Datei...
AHA! Genau diese Ausgabe habe ich doch gesucht.

Wühle mich mal durch.

Nochmal Danke!

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ja.
> Das Problem ist: Das ist ein zweischenidiges Schwert. Es kommt oft auf
> die genauen Umstände an, was konkret funktioniert und was nicht. Und mit
> der nächsten Compilerrelease kann sich vieles ändern.

Was haltet ihr von Wettbewerben. Wer erzeugt den kleinsten Code? Oder 
den schnellsten. Mit so ner ewigen Bestenliste, samt Code.
Als Beispiel irgendeine häufiger vorkommende Aufgabe, wie Tasten 
entprellen, Sinus-PWM oder dergleichen.
Hardware vorgegeben, C sollte es sein, aber Compiler und Schalter, Art 
der Programmmierung kann sich jeder selbst aussuchen... Da hätte man 
gleich viele Beitragende und Erkenntnisse.
Nur so ne Idee.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was geht denn hier ab:

ISR( ADC_vect ){   // Regelschleife wird mit ca 125kHz/13 = ca. 10kHz 
ausgeführt
 10e:  1f 92         push  r1
 110:  0f 92         push  r0
 112:  0f b6         in  r0, 0x3f  ; 63
 114:  0f 92         push  r0
 116:  11 24         eor  r1, r1
 118:  1f 93         push  r17
 11a:  2f 93         push  r18
 11c:  3f 93         push  r19
 11e:  4f 93         push  r20
 120:  5f 93         push  r21
 122:  6f 93         push  r22
 124:  7f 93         push  r23
 126:  8f 93         push  r24
 128:  9f 93         push  r25
 12a:  af 93         push  r26
 12c:  bf 93         push  r27
 12e:  cf 93         push  r28
 130:  df 93         push  r29
 132:  ef 93         push  r30
 134:  ff 93         push  r31

Das ist normal, oder?

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

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Was geht denn hier ab:

Kommt drauf an.
Was machst du in der ISR?
Funktionsaufrufe solltest du nach Möglichkeit vermeiden. Dann kann es 
schon dazu kommen, dass der Compiler erstmal die halbe CPU sichern muss. 
Daher ist es des öfteren besser, in der ISR nur ein Jobflag zu setzen 
und die eigentliche Arbeit in der Hauptschleife zu machen.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Das ist normal, oder?

Wenn du aus der ISR eine andere Funktion aufrufst, schon.

Oliver
P.S. Die Compileroption -Os nutzt du aber, oder?

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja -Os verwende ich. Soweit ist klar...

Hab zwei Verdächtige aufgemacht:

- Die ISR erzeugen einigen Overhead, da ich aus Ihnen heraus Funktionen 
fleißig aufrufe, um den Code besser zu strukturieren. --> Abhilfe Flags 
und Hauptschleife verwenden.

- Verdacht, dass die Bitfelder mehr Schaden als Nützen. RAM hab ich noch 
und Ausführungszeit ist unkritisch(-er). Mal schauen was das bringt. 
Werde berichten.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> - Verdacht, dass die Bitfelder mehr Schaden als Nützen. RAM hab ich noch
> und Ausführungszeit ist unkritisch(-er). Mal schauen was das bringt.
> Werde berichten.

Nochmal 5% wegen einem Statusbyte als Bitfeld.... Habs jetzt auf Bytes 
aufgeteilt.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann einigen Platz sparen, wenn viele Funktionsaufrufe vorhanden sind 
(auf Kosten der Geschwindigkeit):

-mcall-prologues

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:
> Kann einigen Platz sparen, wenn viele Funktionsaufrufe vorhanden sind
> (auf Kosten der Geschwindigkeit):
>
> -mcall-prologues

Danke für den Tip. Hab ich schon probiert: Der einzige Schalter bei dem 
der Code deutlich gewachsen ist....

Regler schrieb:
> - Die ISR erzeugen einigen Overhead, da ich aus Ihnen heraus Funktionen
> fleißig aufrufe, um den Code besser zu strukturieren. --> Abhilfe Flags
> und Hauptschleife verwenden.

Hat leider nur 0.6% gebracht. Viel Arbeit, macht auch Sinn, aber leider 
wenig Ergebnis. Hoffe keine Fehler eingebaut zu haben.

Übrigens kompiliert der Code mit 2% weniger Code, wenn ich auf ein Array 
über ein Struct zugreife, als wenn ich das Array direkt benutze, ohne es 
in ein Struct einzubetten.

Eigenartiges Ergebnis....

Hab jetzt weitere 10 Prozent zum Debuggen bzw. Ergebnis optimieren. Bin 
aber für weitere Hacks dankbar...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> - Erzeugt die Verwendung von Bitfeldern zwar schnelleren, aber größeren
> Code? Oder andersrum?

Solange es nicht konstante Ausdrücke sind, die zur Compilezeit berechnet 
werden, sind Bitfelder recht umständlich.
Deshalb sieht man oft, daß für eine Bitvariable ein ganzes Byte benuzt 
wird.

> - Wie geht man am geschicktesten mit globalen Variablen um, wenn man
> speicher sparen will?

Vermeiden, d.h. lokale Variablen, wenn möglich.

> - Welche Zugriffe erzeugen viel Code, welche nicht?

Puh, da gibts keine kurze Antwort.
Z.B. variables Schieben ist teuer, kann man aber fast immer in Schieben 
um 1 umformen.


> - Dito für Operanden, C-Strukturen (Funktionen, Auslagern in externe
> Dateien, ...)?

Flache Strukturen, also möglichst wenige Zeiger auf Zeiger auf Zeiger 
auf ...


> - Ab wie vielen Zugriffen aus dem Programm ist das Auslagern in eine
> Funktion sinnvoll?

Ab 2.


Bewährte Optimierungsschalter sind:
-fno-inline-small-functions
-fno-tree-scev-cprop
-fno-split-wide-types
-Wl,--relax
--combine -fwhole-program


Peter

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Solange es nicht konstante Ausdrücke sind, die zur Compilezeit berechnet
> werden, sind Bitfelder recht umständlich.
> Deshalb sieht man oft, daß für eine Bitvariable ein ganzes Byte benuzt
> wird.

Was meine Optimierung bestätigt.(s.o.) Waren schon fast 5%. Hat mich 
zwar 4 weitere Bytes gekostet, aber was solls...

> Vermeiden, d.h. lokale Variablen, wenn möglich.

Lustigerweise hab ich hierbei das Gegenteil erfahren: der Code wuchs um 
4% durch das Einlagern einer struct-Variablen und übergeben des Zeigers 
an die Funktionen, die Zugriff benötigten. Also global gelassen.

> Z.B. variables Schieben ist teuer,

Was meinst Du mit variabel? Zur Laufzeit festgelegt?

> kann man aber fast immer in Schieben
> um 1 umformen.
Die Aussage verstehe ich nicht. Wie kann man Schieben um z.B. 7 mit 
Schieben um 1 ersetzen? Verwende die Möglichkeit zu dividieren durch 
Schieben fleißig...

> Flache Strukturen, also möglichst wenige Zeiger auf Zeiger auf Zeiger
> auf ...

Das dachte ich auch, war aber beim Array in einem Struct (das sind ja 
auch Zeiger-auf-Zeiger-Operationen, oder?) eben genau anders herum. 
(s.o.)

> Bewährte Optimierungsschalter sind:
> -fno-inline-small-functions

Brachte 5% s.o.

> -fno-tree-scev-cprop

0 Byte

> -fno-split-wide-types

0 Byte

> -Wl,--relax

0 Byte

> --combine -fwhole-program

Kompiliert leider nicht mehr....

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Kompiliert leider nicht mehr....

DAS HÄTTE EINE WARNUNG SEIN SOLLEN! !%#§$=?!

Das Programm war wohl etwas zuviel optimiert worden von den vielen 
Schaltern... War irgendein Bug drin (......laaaaaaange gesucht, nichts 
gefunden....).

Alle Schalter zurückgesetzt. Schwupps und schon funktionierts!

Ein Glück scheint mein Lieblingsschalter -fno-inline-small-functions 
NICHT Schuld zu sein! Den hab ich dann doch wieder eingeschaltet.

Aber ab sofort bin ich ein gebranntes Kind, was diese Schalter angeht. 
Musste ja einen Grund geben, dass die standardmäßig nicht alle gesetzt 
sind!
Die meisten haben aber eh nicht viel gebracht.

Also: Seid gewarnt. Hat mich etwas arg viel Zeit und Nerv gekostet.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Z.B. variables Schieben ist teuer, kann man aber fast immer in Schieben
> um 1 umformen.

Also sowas, wobei pwmmode eine Variable ist?
....
#define LEDPORT    PORTB
#define LEDON(x) (LEDPORT &= ~(x)) // LEDs sind active low
#define LEDOFF(x) (LEDPORT |= (x))
....
LEDON(1<<pwmmode);
LEDOFF(1<<pwmmode);
...

Folgendes ist zwar kürzer, aber nicht wirklich viel:
LEDOFF(pwmmode?2:1);

Gibt es bessere Möglichkeiten?

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch 1%:

...
void main(void) __attribute__((noreturn));

void main(void){
....

mit -ffreestanding kompiliert...

Autor: Tom B. (botas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu dem Thema kann man zwei Bücher empfehlen:

Hackers Delight
http://www.amazon.de/Hackers-Delight-Henry-S-Warre...

und natürlich das Drachenbuch um zu verstehen was beim Compilieren 
eigentlich so passiert

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also hat sich gelohnt, trotz Ärger....

Fazit:
- Als allererstes Compilerflags "pimpen". Aber auch die Funktion des 
Kompilats IMMER überprüfen (Ausführungszeit und Funktion). NICHT davon 
ausgehen, dass sich am Ergebnis außer der Codegröße nichts ändert.
- Bitfelder: Finger weg. Viel mehr Code, aufwendiger. Sollte nicht mal 
Zeit sparen. Lieber ganze Bytes für logische Operatoren verwenden.
- KEINE Funktionsaufrufe aus ISR. Aufwendig, selbst wenn klein.
- Main als non-returning definieren.
- Structs scheinen zur Organisation von Daten ganz nützlich zu sein.
- Bestätigt auch folgende Seite, die auch noch andere nützliche Tips und 
Erklärungen hat:
http://www.tty1.net/blog/2008-04-29-avr-gcc-optimi...
- Ein Blick in die lss lohnt sich. Man kann gut erkennen, wo Mist gebaut 
wurde.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> War irgendein Bug drin (......laaaaaaange gesucht, nichts
> gefunden....).

Nochmal Ärger, wegen meiner Dummheit: Bug war (mal wieder) vorm PC. 
Konnte mir auch nicht vorstellen, dass der Compiler schuld war.

Wenn man eine neue Configuration im AVR-Studio anlegt, erfolgt die 
Ausgabe der hex-Datei in einem neuen Verzeichnis. Und das muss man 
natürlich auch (selbst!!!) im Programmiermenü ändern. Wie konnte ich 
übersehen, dass ich immer wieder und wieder das alte Programm geladen 
habe.

Das konnte gar nicht funktionieren....

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
>> --combine -fwhole-program
>
> Kompiliert leider nicht mehr....

Dazu muß man dem Compiler alle Sourcen in einem Rutsch übergeben, also 
nicht nacheinander.
Alternativ übergibt man nur ein C-File, was alle anderen included.
Oder compiliert nicht mit Make, sondern einer Batch, die das Argument 
*.c expandiert.

Diese Optimierung geht sehr radikal über alles, entfernt unnötige Calls 
und allen toten Code.


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was (nur beim WINAVR) sehr teuer ist, sind EEPROM-Zugriffe.
Da wird quasi ein BIOS installiert und von hinten durch die Brust ins 
Auge aufgerufen (indirekter Call).

Deutlich kürzer und schneller geht es so:

http://www.avrfreaks.net/index.php?name=PNphpBB2&f...

Die Routine fängt sogar unnötige Schreibzugriffe ab.


Peter

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Alternativ übergibt man nur ein C-File, was alle anderen included.

Etwa so:
#include "beispiel.h"
// und
#include "beispiel.c"
?

Peter Dannegger schrieb:
> Deutlich kürzer und schneller geht es so:
>
> http://www.avrfreaks.net/index.php?name=PNphpBB2&f...
>
> Die Routine fängt sogar unnötige Schreibzugriffe ab.

Ich verwende tatsächlich den Eeprom.... Mmmmhhh. Schau ich mir mal 
genauer an. Werde berichten.
Danke für die Hilfe, Peter! ;)

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Regler schrieb:
>>> --combine -fwhole-program
>>
>> Kompiliert leider nicht mehr....
>
> Dazu muß man dem Compiler alle Sourcen in einem Rutsch übergeben, also
> nicht nacheinander.
> Alternativ übergibt man nur ein C-File, was alle anderen included.
> Oder compiliert nicht mit Make, sondern einer Batch, die das Argument
> *.c expandiert.
>
> Diese Optimierung geht sehr radikal über alles, entfernt unnötige Calls
> und allen toten Code.


WOW!
Peter!
Respekt.

Stellt alle anderen Mühen echt in den Schatten. Habe sofort fast 20% 
gespart. Qualitativ sehr hochwertiger Tip und Empfehlung an alle, die 
sich auch damit rumschlagen (müssen)... Hoffe der Code tut noch was er 
soll.

1000 DANK und meine Empfehlung als Tipgeber des Monats!

Langsam kann ich wieder darüber nachdenken übersichtlich zu 
programmieren ohne immer auf den Platz zu achten!

Den 2. Tip werde ich mir jetzt auch noch genau anschauen!

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Ich verwende tatsächlich den Eeprom.... Mmmmhhh. Schau ich mir mal
> genauer an. Werde berichten.

2%... Da scheint bereits der Schalter ordentlich aufgeräumt zu haben

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Stellt alle anderen Mühen echt in den Schatten. Habe sofort fast 20%
> gespart

Das konnte ja nicht wahr sein. Soooo schlecht hab ich auch nicht 
programmiert. Ergebnis war einer umfangreichen Berechnung, die ich ins 
Leere umgelenkt habe, geschuldet. Das scheint der Compiler mit diesem 
Schalter zu erkennen und ganz wegzukürzen.
Daher alles einkommentieren und alle Funktionen verwenden, wenn man den 
Schalter verwenden will.

Kann leider nicht im Nachhinein sagen, wieviel der Schalter Netto 
gebracht hat. Sorry. Ist mir erst aufgefallen, als ich den Code 
bearbeitet habe, kompiliert und stets die gleiche Code-Größe bekam.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> --combine -fwhole-program

Erfordert die Einbindung der zu den .h zugehörigen .c-Dateien.

Kann man die konditional (d.h. mit einer #ifdef-Anweisung) in 
Abhängigkeit des Flags mit dem Präprozessor einbinden? Damit muss man 
das nicht immer händisch ändern und hält den Code portabel.

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.