Forum: Compiler & IDEs Size Benchmark mit GCC, Imagecraft und IAR


von Mehmet K. (mkmk)


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

von Sebastian (Gast)


Lesenswert?

Hallo,
es wäre schön wenn du CodevisionAVR noch in den Test einbeziehen
könntest und dein Programm hier rein stellen könntest also die C
sourcen.

MfG
Sebastian

von peter dannegger (Gast)


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

von Fabian Scheler (Gast)


Lesenswert?

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)?

Ciao, Fabian

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


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.

von Mehmet K. (mkmk)


Lesenswert?

@Jörg Wunsch

Also den Code möchte ich nicht public machen, aber waere gerne dazu
bereit, diesen Dir persöhnlich und nur zu Testzwecken zukommen zu
lassen.
Wenn Du mir also Deine email Adressen nennen würdest ...

MfG

von Mehmet K. (mkmk)


Lesenswert?

@Sebastian

Den Codevision haette ich auch gerne getestet, aber deren Trialversion
ist leider size-limitiert, weshalb ein Test nicht möglich ist.

MfG

von peter dannegger (Gast)


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

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


Lesenswert?

> Wenn Du mir also Deine email Adressen nennen würdest ...

Nun, Gugel hätte dir sicher mehr als eine erzählt. :)

joerg_wunsch +at+ uriah.heep.sax.de

von Mehmet K. (mkmk)


Lesenswert?

@Jörg

Mail ist unterwegs ....
Na, bin dann mal gespannt, wie das Resultat ausfallen wird.

MfG

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


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.

von Mehmet K. (mkmk)


Lesenswert?

Es ist richtig, dass einige Funktionen nicht benutzt werden.

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


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).

von Mehmet K. (mkmk)


Lesenswert?

Kannst Du bitte die Dateien scheduler.c und standby.c löschen.

von Mehmet K. (mkmk)


Lesenswert?

@Jörg

Beim Imagecraft hat das Löschen der Dateien zu keiner Aenderung in der
Grösse des erzeugten Codes geführt. Beim GCC gab's aber eine eklatante
Steigerung von 7170 auf 7596 Bytes. (... Kopfkratzen ... )

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


Lesenswert?

Wenn ich die beiden Dateien lösche, komme ich auf 6940/7372 Bytes
(ATmega8/16).  Mit oder ohne Bibliothek ist dann egal.

von Mehmet K. (mkmk)


Lesenswert?

Gelten diese Werte für den 4.1 Compiler?
Gilt weiterhin Deine obige Aussage, dass es sogut wie keinen Unerschied
zwischen 3.4.5 und 4.1 gibt?

von Sebastian (Gast)


Lesenswert?

Hallo Mehmet,
kannst du mit den Code unter:
netforum@gmx.de zukommen lassen?
Ich würde dann mal ein Test mit CodevisionAVR machen.

Sebastian

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


Lesenswert?

> Gilt weiterhin Deine obige Aussage, dass es sogut wie keinen
> Unerschied zwischen 3.4.5 und 4.1 gibt?

Ja, zumindest für den ungepatchten.  Björn Haases Patch muss
ich erst noch einbauen.

von Fabian Scheler (Gast)


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

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

> (-ffunction-sections + -gc-sections hat übrigens nichts gebracht,
> erst die Methode mit der Bibliothek.)

Das ist seltsam, beim arm-elf-gcc funktioniert das einwandfrei.

Was noch helfen könnte ist -combine mit -fwhole-program.

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.