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
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
"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
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
> 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.
@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
@Sebastian Den Codevision haette ich auch gerne getestet, aber deren Trialversion ist leider size-limitiert, weshalb ein Test nicht möglich ist. MfG
@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
> 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
@Jörg Mail ist unterwegs .... Na, bin dann mal gespannt, wie das Resultat ausfallen wird. MfG
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.
Es ist richtig, dass einige Funktionen nicht benutzt werden.
> 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).
Kannst Du bitte die Dateien scheduler.c und standby.c löschen.
@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 ... )
Wenn ich die beiden Dateien lösche, komme ich auf 6940/7372 Bytes (ATmega8/16). Mit oder ohne Bibliothek ist dann egal.
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?
Hallo Mehmet, kannst du mit den Code unter: netforum@gmx.de zukommen lassen? Ich würde dann mal ein Test mit CodevisionAVR machen. Sebastian
> 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.
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
> (-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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.