Size Benchmark mit GCC, Imagecraft und IAR

OP #365608
Lesenswert?

Guten Tag allerseits

Da ich mit meinem Imagecraft Compiler schon seit langem etwas
unzufrieden bin und für ein neues Project die Weichen neu stellen
möchte, habe ich mir die Mühe gemacht, die Trial-Versionen von Atman
und Iar zu beziehen und diese untereinander zu testen. Dabei liess ich
die Frage nach der Geschwindigkeit des erzeugten Codes beiseite, da
Geschwindigkeit in meinen Projekten nie eine Rolle spielt.

GCC von Atman (gcc-3.4.5)
Imagecraft (6.31A / prof.)
IAR (4.12A)

Der übersetzte Code enthaelt sogut wie keine Array's im Flash; will
sagen, der ganze Code ist 100% Arbeit für den Controller.
Alle Compiler wurden auf beste Size-Optimierung eingestellt und es
wurde ebenfalls auf C++ verzichtet.
Die erste Ziffer gibt die Grösse für den Controller Atmega8, die zweite
für den Controller Atmega16 in Bytes an. Dabei ist mir aufgefallen, dass
alle Compiler für den Atmega8 einen viel kompakteren Code erzeugen.

     Atmega8   Atmega16
GCC: 7170   /  7604
ICC: 7288   /  7680
IAR: 5950   /  6298


Beim IAR wurde ich misstrauisch und habe den erzeugten Code in das
Geraet geladen: laeuft einwandfrei.

Meine persönliche Entscheidung: Ich werde bei der Auswahl des
Controllers eine Nummer grösser einsteigen und GCC nehmen.

MfG
Gast #365610
Lesenswert?

"Dabei ist mir aufgefallen, dass alle Compiler für den Atmega8 einen
viel kompakteren Code erzeugen."

Bis 8kB werden RCALL und RJMP verwendet, darüber sind alle Calls und
Jumps doppelt so groß (4 Byte).


Daß der IAR deutlich kleineren Code erzeugt, wird wohl daran liegen,
daß er 8Bit Berechnungen auch 8Bittig ausführt. Der GCC dagegen
erweitert oft unnötiger Weise auf 16Bit, z.B. bei switch-Anweisungen.


Peter
Moderator Persönliche Seite #365612
Lesenswert?

> Daß der IAR deutlich kleineren Code erzeugt, wird wohl daran liegen,
> daß er 8Bit Berechnungen auch 8Bittig ausführt. Der GCC dagegen
> erweitert oft unnötiger Weise auf 16Bit, z.B. bei
> switch-Anweisungen.

Außerdem kann der IAR gerade bezüglich der RJMPs einiges optimieren,
d. h. alle JMPs, deren Ziel innerhalb der ±4-KB-Grenze liegt, werden
zu RJMPs gewandelt.  Björn Haase hat etwas ähnliches mittlerweile für
den GCC 4.x vorgestellt, er benutzt es auch bereits in
Produktionscode, ich hab's mir aber noch nicht angesehen.

Der GCC 4.1.0 ist nach meinen Erfahrungen in der Codegröße irgendwo in
der Mitte zwischen dem GCC 3.4.x und dem IAR, insofern wäre es
interessant, den gleichen Code auch noch einmal auf einem GCC 4.1.0 zu
testen.  Mehmet, falls du den Code freigeben kannst, biete ich mich
für einen Test an.  Ich würde mich ggf. auch bereit erklären, den Test
danach noch einmal mit einem gepatchten GCC 4.x mit dem linker
relaxation patch von Björn zu testen.

> Hast du beim GCC nur die Option -Os verwendet, oder hast du auch
> -ffunction-sections bzw. -fdata-sections verwendet (in Kombination
mit
> -gc-sections beim Linker)?

Das bringt bei ordentlichem Code rein gar nichts.  Nur, wenn der
Programmierer nicht wusste, was er alles aufgeschrieben hat, und
dadurch toter Code entstanden ist, kann man damit was rausholen.
Gast #365615
Lesenswert?

@Jörg

"Außerdem kann der IAR gerade bezüglich der RJMPs einiges
optimieren"

scheint sich aber nicht groß auszuwirken, der Unterschied 8kB/16kB ist
bei IAR und GCC etwa gleich (6%).


Peter
Moderator Persönliche Seite #365618
Lesenswert?

Hmm, ich habe für die Anzahl der scheduler mal eine Hausnummer
eingetragen... aber ich vermute, dass die Codegröße davon nicht
abhängt, nur der RAM-Verbrauch.

Interessanterweise komme ich mit einem ungepatchten GCC 4.1.0 auf
gleiche Größen wie der GCC 3.4.5 dir gebracht hat.

Aber: ich habe mal alle .o-Dateien außer main.o in eine
Bibliothek gestopft und dann beim Linken lediglich main.o
plus diese Bibliothek angegeben, sodass nur die tatsächlich
benötigten Objektmoduln gelinkt werden.  Damit komme ich auf:

ATmega8 ATmega16
6996    7372

Immer noch ein gutes Stück entfernt von den IAR-Werten, aber ich
vermute, du hast noch ein wenig ,,Aufräumpotenzial'', da
offenbar nicht alle Funktionen wirklich benutzt werden.
(-ffunction-sections + -gc-sections hat übrigens nichts gebracht,
erst die Methode mit der Bibliothek.)

Ich werde mir noch Björns linker relaxation Patch mal reinziehen.
Kann aber ein, zwei Tage dauern.
Moderator Persönliche Seite #365620
Lesenswert?

> Es ist richtig, dass einige Funktionen nicht benutzt werden.

Die werden aber bei GCC trotzdem alle gelinkt, weil du ja alle
.o-Dateien auf der Kommandozeile angegeben hast.  IAR linkt
(vermutlich) nur referenzierte Funktionen.  Die Bibliotheks-
Methode linkt zumindest nur die Objektmodule, die wirklich
referenziert werden (die aber trotzdem noch komplett, also
wenn eine Funktion referenziert wird, wird alles gelinkt).
Gast #365627
Lesenswert?

Das mit den verschiedenen Größen bezüglich Bibliothek und gelöschten
bzw. nicht gelöschten Source-Files ist klar: wirft man dem GNU Linker
ein Objekt-File hin, wandert es auch in die ausführbare Datei, ob ein
Symbol daraus referenziert wird oder nicht ... bei Bibliotheken ist
dies nicht der Fall.

Zum Thema: -ffunction-sections + -gc-sections
Bei typischen Embedded-Toolchains arbeiter der Linker standardmäßig als
smart Linker, diese beiden Optionen sind hier also stanardmäßig
aktiviert, bei der GNU Toolchain ist dies nicht der Fall. Das Argument
aufgeräumter Code zieht nicht - wenn man etwas implementiert sollte man
immer darauf achten Belange zu trennen, was zusammen gehört sollte  aber
auch in dieselbe Überstzungseinheit wandern (z.B. der Übersichtlichkeit
halber, die Implementierung einer C++-Klasse), man muss aber nicht
unbedingt immer alle Methoden referenzieren, die in einer
Übersetzungseinheit implementiert sind.

Ciao, Fabian

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren