Forum: Compiler & IDEs Compilereinstellung für möglichst kompakten Code (gcc)


von Christian B. (christianbesemann)


Lesenswert?

Hallo zusammen,

meinem Atmel geht so langsam der Flash aus, bin mir aber nicht sicher ob 
der compilierte Code eventuell noch von mir nicht benötigte Infos 
beinhaltet (debuggen etc).

Ich würde gerne den Compiler dazu veranlassen möglichst kompaktesten 
Code zu erzeugen, kenne mich aber mit den Schaltern des Compilers im 
Makefile nicht aus.

Kann mir hier bitte jemand Hilfestellung geben, hab schon im Forum 
gesucht, bisher ohne Erfolg. Vielen dank schon mal!!!

Grüße
Chris

von Juergen (Gast)


Lesenswert?

-Os

von Christian B. (christianbesemann)


Lesenswert?

Danke, ich poste mal den Abschnitt des Compilers aus "meinem" Makefile:

#---------------- Compiler Options ----------------
#  -g*:          generate debugging information
#  -O*:          optimization level
#  -f...:        tuning, see GCC manual and avr-libc documentation
#  -Wall...:     warning level
#  -Wa,...:      tell GCC to pass this to the assembler.
#    -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct 
-fshort-enums
CFLAGS += -Wall -Wstrict-prototypes
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)

ich weiß damit nicht wirklich was anzufangen...brauche daher den 
Expertenrat! Was muss ich hier ändern, wo muss das -Os hin.

von ... (Gast)


Lesenswert?

Du hättest das komplette Makefile posten sollen!
Irgendwo steht da bestimmt eine Zeile:
1
OPT=...
Die mußt Du ändern in:
1
OPT=s

CU

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Christian Besemann wrote:
> Hallo zusammen,
>
> meinem Atmel geht so langsam der Flash aus, bin mir aber nicht sicher ob
> der compilierte Code eventuell noch von mir nicht benötigte Infos
> beinhaltet (debuggen etc).
Falls "nicht benötigte Infos" Funktionen oder globale/statische 
Variablen sind: vgl. Compileroptionen -ffunction-sections, 
-fdata-sections und Linker-Option -gc-sections(beim Linken über 
Frontend: -Wl,--gc-sections).

> Ich würde gerne den Compiler dazu veranlassen möglichst kompaktesten
> Code zu erzeugen, kenne mich aber mit den Schaltern des Compilers im
> Makefile nicht aus.
Erstmal das genannte -Os, weiter Tuningmäglichkeiten wurden hier schon 
mehrmals diskutiert, z.B. Beitrag "WinAVR 20080402"

> Kann mir hier bitte jemand Hilfestellung geben, hab schon im Forum
> gesucht, bisher ohne Erfolg.
vgl. z.B. o.g. Link

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Christian Besemann wrote:
> Hallo zusammen,
>
> Ich würde gerne den Compiler dazu veranlassen möglichst kompaktesten
> Code zu erzeugen, kenne mich aber mit den Schaltern des Compilers im

Als Optionen kann man folgendes antesten:
1
-fno-tree-scev-cprop
2
-fno-split-wide-types
3
-fno-inline-small-functions
4
-fno-move-loop-invariants
5
-morder1

Für jede dieser Optionen sollte man separat testen, wie sie auf den 
jeweiligen Code wirkt, denn je nach Codestruktur kann sie eine 
Verkleinerung oder Vergrößerung bewirken.

-fno-split-wide-types hat weiterhin den Vorteil, daß mit ihr ein Bug in 
WinAVR-20090313 bzw. WinAVR-20081205 nicht zum Tragen kommt.

Die obigen -f Optionen sind für gcc 4.x (also auch für avr-gcc 4.x), die 
-m nur für avr-gcc.

Den kleinsten Code erhalte ich mit avr-gcc 3.4.6, allerdings hab ich 
noch nicht mit avr-gcc 4.4.0 oder avr-gcc 4.5 verglichen, nur gegen <= 
4.3.3

Um kleinen Code zu erhalten ist es ratsam, ein Review der Quelle 
durchzuführen, um Codefresser zu eliminieren. Dazu muss man natürlich 
den erzeugten Assembler-Code zu bewerten in der Lage sein und eine 
Vorstellung davon haben, wie guter gcc-Code aussieht.

Eine weitere Fingerübung in Makefile wäre es, jede Quelldatei mit 
mehreren Sätzen von gcc-Schaltern zu übersetzen, und nur das Objekt zu 
linken, das den kleinsten Code ergibt. Das hab ich mal für den Build 
eines Projektes durchgezogen. Die Build-Zeit geht natürlich linear mit 
der Anzahl der Schalterkombinationen nach oben. Allerdings war auch hier 
avr-gcc 3.4.6 konkurenzlos...

> meinem Atmel geht so langsam der Flash aus, bin mir aber nicht sicher ob
> der compilierte Code eventuell noch von mir nicht benötigte Infos
> beinhaltet (debuggen etc).

Beim Erstellen des hex-Files sollten nur Sections wie .text oder .eeprom 
eingehen, .stabs, .info, .debug etc. hat da nix zu suchen. SChau einfach 
auf der Kommandozile, welcher Optionen avr-objcopy mitbekommt, wenn es 
aus dem .elf (das alle Infos, also auch debug-Infos) enthält, das .hex 
erzeugt.

Johann

von Oliver (Gast)


Lesenswert?

> meinem Atmel geht so langsam der Flash aus, bin mir aber nicht sicher ob
> der compilierte Code eventuell noch von mir nicht benötigte Infos
> beinhaltet (debuggen etc).

Die erzeugten hex-Files ernthalten bei avr-gcc niemals Debuginfos. Diese 
stecken in zusätzlichen Dateien, die nicht in den Controller geladen 
werden.

Aber: der beste Optimizer bzw. größte Flashverschwender sitzt 
erfahrungsgemäß vor dem Computer...

Hast du deinen Code schonmal durchforstet, ob da alles wirklich so sein 
muß, wie es ist?

Und falls es sich um ein Hobbyprojekt in Stückzahl 1 handelt: Gibt es 
einen pincompatiblen AVR mit mehr FLASH?

Oliver

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Oliver wrote:

> Die erzeugten hex-Files ernthalten bei avr-gcc niemals Debuginfos. Diese
> stecken in zusätzlichen Dateien, die nicht in den Controller geladen
> werden.

Das hängt einzig und alleine davon ab, wie ein hex-File erzeugt wird. Es 
kann ebenfalls debug-Informationen enthalten (die darin allerdings 
ziemlich sinnfrei sind), denn man sie vom .elf ins .hex übernimmt.

Johann

von Bernhard M. (boregard)


Lesenswert?

Johann L. wrote:
> Das hängt einzig und alleine davon ab, wie ein hex-File erzeugt wird. Es
> kann ebenfalls debug-Informationen enthalten (die darin allerdings
> ziemlich sinnfrei sind), denn man sie vom .elf ins .hex übernimmt.
>
> Johann

Rein interessehalber, wie soll das gehen? Die Debug-Info selbst hat doch 
keine Adresse, auf welche Adresse wird sie dann im HEX File gelegt?

von Klaus (Gast)


Lesenswert?

Nichts was im hex-File landet hat von sich aus eine Adresse. Erst der 
Linker weist jedem Teil eine Adresse zu. Das kann er mit Programmcode 
genauso machen wie mit debug infos oder sonstigen Daten. Auch wenn wie 
erwähnt, diese Diskusion sinnfrei ist, weil debug infos im Controller 
ebend sinnfrei sind. ;)

von Oliver (Gast)


Lesenswert?

>Nichts was im hex-File landet hat von sich aus eine Adresse. Erst der
>Linker weist jedem Teil eine Adresse zu.

http://de.wikipedia.org/wiki/Intel_HEX

Der Linker kommt lange vorher...

Oliver

von Klaus (Gast)


Lesenswert?

Das heißt, im elf-File hat alles schon seine Adressen und darauf werden 
dann einzelne Sectionen ins Hex-File übertragen? Dann schließe ich mich 
der Frage von  Bernhard M. (boregard) an ;)

von Christian B. (christianbesemann)


Lesenswert?

Hallo,

wenn ich die Expertendiskussion kurz unterbrechen darf, vielen dank 
schon mal für die geleisteten Beiträge, das mit dem größten 
Flashverbraucher vor der Tastatur ignoriere ich mal ;-)) - allein proggt 
er sich nun mal nicht der Atmel....

Ja es ist ein Hobbyprojekt und ich könnt auf einen großen Bruder 
ausweichen, so will ich doch bei aller "Spielerei" auch was lernen - in 
diesem Fall über die Compilerschalter. Gibt es eine Doku / Beschreibung 
zu deren Verwendung?

Grüße Chris

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Christian Besemann wrote:

> Ja es ist ein Hobbyprojekt und ich könnt auf einen großen Bruder
> ausweichen, so will ich doch bei aller "Spielerei" auch was lernen - in
> diesem Fall über die Compilerschalter. Gibt es eine Doku / Beschreibung
> zu deren Verwendung?
>
> Grüße Chris

Erste Hinweise erhält man per
1
avr-gcc -v --help

eine auf Optimierung gefilterte Ausgabe mit
1
avr-gcc --help=optimizers

Etwas mehr Prosa gibt's direkt bei gcc:
   http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Optimize-Options.html#Optimize-Options
wobei für avr nicht alles implementiert ist, zB bleibt 
-foptimize-sibling-calls ohne Wirkung, obwohl die Optimierung für avr 
machbar ist. Nur hat's eben noch keiner gemacht...

Letztendliche Klarheit liefern die Compiler-Quellen -- zumindest glaubt 
das Lieschen Müller...

Für die oben genannte -fsplit-wide-types wäre ein erster Anlaufpunkt 
dann
   http://gcc.gnu.org/viewcvs/tags/gcc_4_3_3_release/gcc/lower-subreg.c?revision=143643&view=markup

Johann

von Christian B. (christianbesemann)


Lesenswert?

Danke an die Beitragenden!!!

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.