Forum: Mikrocontroller und Digitale Elektronik Vergleich C Compiler


von Sebastian__ (Gast)


Lesenswert?

Hallo,
ich möchte jetzt ein paar Projekte mit verschieden AVR Controller in C
realisieren.
Welche der Folgenden C Compiler ist der Beste, für mich spielt die
Codezize und Workingspeed gefolgt von der unterstützung der
verschiedenen Controller ung Qualität der IDE eine Rolle.
Alles mal abgesehen vom anschaffungspreis der Compiler.

1. AVRGCC
2. CodeVision AVR Prof.
3. ImageCraft AVR C

Wo liegen die vor und nachteile dieser Compiler? Gibt es irgendwo
Benchmarkes? So in etwa auf jedem Compiler der selbe C code und dann
messen welcher am schnellsten ist und welche Codezize am geringsten
ist.
Ich habe bis jetzt zu 80% alles in ASM gemacht und komme damit auch
sehr gut zurecht, aber die entwicklungszeit der SW ist doch sehr lang
im vergleich zu einer SW die man teilweise in C schreiben kann.

Danke

MfG
Sebastian

von BAB (Kai K.) (Gast)


Lesenswert?

mach dir selbst ein bild...es gibt von allen testversionen

von crazy horse (Gast)


Lesenswert?

einen effektiven Vergleich kann es gar nicht geben, jeder wird Stärken
und Schwächen haben, den ultimativen besten wird es nicht geben. Es
kann sein, du wählst Testbedingungen, in der ein Compiler besondere
Schwächen hat und besondere Vorzüge gar nicht zum Tragen kommen -
Ergebnis: Compiler ist Sch...
Stimmt aber gar nicht, mit anderen Testbedingungen hätte es ganz anders
ausgesehen. Ausserdem sind Compiler immer Baustellen, welche mit jedem
feedback von den usern besser wird, kein Programmierer kann von Hause
aus optimale Algorithmen einbauen.
Bei mir stand die Wahl zwischen CodeVision und IAR, CodeVision hat mir
sehr zugesagt, letztendlich war auch der Preis ein Argument.

von Sebastian__ (Gast)


Lesenswert?

sagen wirs mal anders, wo liegen den die vor und nachteile von
bestimmten compilern, die bekommt man ja meist erst nach einiger zeit
und intensiver benutzung mit. Was mich zb. an GCC etwas stört bzw. was
es in meiner gunst sinken lässt ist die unübersichtlichkeit der
Biblioteken und dern handling, zum mal was basteln is es ja ok, aber
wenn man was ernsthaftes machen will muss man sich ja wenigstends auf
eine komponente verlassen können und nicht noch im compiler ständig
nach fehlern suchen.
Bei der Effizienz der Compiler geht es mir Hauptsächlich darum wie gut
sie zb. ein paar verschatelte Schleifen auflösen und eine Handvoll
signed Integer Operationen, hat schon mal jemand getestet wie groß da
die unterschiede zw. den Compilern sind?

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Was meinst du mit "Unübersichtlichkeit der Bibliotheken", und von
welchen Fehlern sprichst du?

von crazy horse (Gast)


Lesenswert?

nö, habe ich nicht, da wird der Unterschied auch nicht besonders groß
sein, das ist trivial.
Deutliche Unterschiede wird vielleicht bei komplizierten math.
Funktionen mit float-Variablen geben, da könnte ich mir schon
vorstellen, dass es da ein paar 100 Takte Unterschied gibt, die
vielleicht bei der nächsten Funktion wieder wettgemacht werden. Wenns
aber so eng wird, dass das einem Design den Garaus macht, hat von
Anfang an zu eng (oder gar nicht) geplant.
Codegröße und Laufzeit kann man auch selbst stark beeinflussen, da
gibts einmal die Compileroptionen und zum anderen die eigene
Programmierweise.

von Sebastian__ (Gast)


Lesenswert?

@Andreas
ich finde zwar diesen Open Source gedamken toll, aber meines erachtens
ist der GCC für mich nicht übersichtlich genug, desweiteren treten
zwischen mit verschiedenen Versionen von Compilierten inkopatiblitäten
und die seltsammsten Fehler auf, die werden zwar dann nach und nach
ergründet, aber das ist dann auch kein Trost wenn man schnell ein
Ergebniss abliefern muss.
Ich werde mir jetzt mal selbst ein Bild davon machen inwiefern die
3Compiler meinen Anforderungen gerecht werden.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Von Inkompatiblitäten ist mir nichts bekannt. Die Funktionen inp(),
outp() und noch ein paar andere wurden für veraltet erklärt, ein paar
.h-Dateien wurden umbenannt, aber trotzdem kompilieren meine alten
Programme noch (zwar mit Warnungen, aber sie kompilieren). Mag sein
dass es beim Umstieg von gcc-2.95 auf 3.0 Probleme gab, aber vor 3.0
war der AVR-GCC sowieso nicht viel mehr als beta. Und leider haben
viele die uralten Windows-Versionen von http://8bit.at/avr/ und
avrfreaks.net noch lange weiterverwendet.

Im Moment ist der Compiler jedenfalls sehr gut benutzbar, die Libraries
sind ausgereift, und der Support ist super. Allerdings haben viele
Windows-User nach wie vor Probleme. Was für einen Unixer
selbstverständlich ist, kann für einen Windows-User völlig
unverständlich sein...

von hebel23 (Gast)


Lesenswert?

Da muss ich Dir Recht geben. Ich habe zwar erst vor ca. 2 Monaten mit
dem AVRGCC angefangen (Version 3.3), bin aber sehr zufrieden damit. Die
Dokumentation ist sehr übersichtlich und der erzeugte Code ist
erstaunlich effizient. Besonders begeistert mich die Mathelibrary, mit
der man auch höhere mathematische Funktionen problemlos implementieren
kann. Ich habe die AVR´s bisher wegen der üblichen Vorurteile auch nur
mit Assembler programmiert, werde das aber in Zukunft nur noch in
Ausnahmefällen tun. Die anderen Compiler kenne ich (noch) nicht.

Gruß Andreas

von Michael (Gast)


Lesenswert?

Vorab:
Ich würde Dir den AVRGCC nahelegen; da bekommst Du hier die beste
Unterstützung.

Da Du schon Assembler programmiert hast, sind die beiden anderen
Compiler nicht so interesant für Dich. Mit denen kann man aber gut
lernen (wie man es nicht macht).

Z.B.: long i; for(i=0;i<70000;i++);
Ein Compiler zeigt Dir ganz genau wie es geht:
Unterprogramm aufrufen, um i mit 0 zu laden
Schleife:
{
  Unterprogramm aufrufen, um 70000 zu laden
  Unterprogramm aufrufen, um Vergleich durchzuführen
  Unterprogramm aufrufen, um i zu inkrementieren
}
Das braucht dann so seine 100 Byte und viel, viel Zeit.

Der andere Compiler zeigt Dir das Gegenteil:
Bei jeder Zuweisung long -> float wird hier 'schneller' Inline-Code
erzeugt. Jedesmal. Ein Unterprogramm würde ja den Lerneffekt
verhindern.

Einer der Compiler optimiert den erzeugten Code am Ende noch einmal.
Nur, wenn man einen µP mit 8K Flash angegeben hat und vor der
Optimierung 8,1K generiert wurden, gibt es keine Optimierung, sondern
Fehler.
Einer schafft bei float Berechnungen nur fünf gültige Stellen: mager.

Persönlich verwende ich den, den crazy horse nicht genommen hat. Der
optimiert teilweise so gut, daß selbst relevante Anweisungen
verschwinden. Aber nicht sofort, sondern erst wenn die Routine
erfolgreich getestet wurde und das Programm anschließend weiter
wächst.

Fazit: s.o. und Du kommst nicht umhin, Dich mit dem Compiler Deiner
Wahl intensiv auseinanderzusetzen, vor und nach der Anschaffung.

von crazy horse (Gast)


Lesenswert?

was willst du damit eigentlich sagen, soll der Compiler so arbeiten,
dass man das Listfile noch versteht (wegen Lerneffekt und so)  oder
soll effektiver Code erzeugt werden?
Habe dein obiges Schleifenbeispiel mal mit CodeVision compiliert:
         ;      84  for(i=0;i<70000;i++);
000056 27ee        CLR  R30
000057 93e0 0084   STS  _i,R30
000059 93e0 0085   STS  _i+1,R30
00005b 93e0 0086   STS  _i+2,R30
00005d 93e0 0087   STS  _i+3,R30
          _0x2D:
00005f 91a0 0084   LDS  R26,_i
000061 91b0 0085   LDS  R27,_i+1
000063 9180 0086   LDS  R24,_i+2
000065 9190 0087   LDS  R25,_i+3
000067   +    __CPD2N 0x11170
000067 37a0        CPI  R26,LOW(0x11170)
000068 e1e1        LDI  R30,HIGH(0x11170)
000069 07be        CPC  R27,R30
00006a e0e1        LDI  R30,BYTE3(0x11170)
00006b 078e        CPC  R24,R30
00006c e0e0        LDI  R30,BYTE4(0x11170)
00006d 079e        CPC  R25,R30
            .ENDM
00006e f4ac        BRGE _0x2E
00006f 91e0 0084   LDS  R30,_i
000071 91f0 0085   LDS  R31,_i+1
000073 9160 0086   LDS  R22,_i+2
000075 9170 0087   LDS  R23,_i+3
000077   +    __SUBD1N -1
000077 5fef        SUBI R30,LOW(-0x1)
000078 4fff        SBCI R31,HIGH(-0x1)
000079 4f6f        SBCI R22,BYTE3(-0x1)
00007a 4f7f        SBCI R23,BYTE4(-0x1)
            .ENDM
00007b 93e0 0084   STS  _i,R30
00007d 93f0 0085   STS  _i+1,R31
00007f 9360 0086   STS  _i+2,R22
000081 9370 0087   STS  _i+3,R23
000083 cfdb        RJMP _0x2D

sehe da nicht viel weitere Optimierungsmöglichkeit, allenfalls die
Schleifenvariable direkt in Registern statt im SRAM abzulegen, dass
macht CodeVision mit long-Variablen prinzipiell nicht, selbst wenn noch
freie Register da wären. Wie löst IAR das Beispiel?

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Mit so einem "Programm" Compiler vergleichen zu wollen, ist völlig
sinnlos, eine leere for-Schleife hat doch keinerlei Funktion.

Nur eine Sache die mir aufgefallen ist:

000077 5fef        SUBI R30,LOW(-0x1)
000078 4fff        SBCI R31,HIGH(-0x1)

Der GCC macht stattdessen einfach "adiw R30, 1".

von Michael (Gast)


Lesenswert?

Mit welchem Compiler ich welches Verhalten hatte (s.o.) weiß ich nicht
mehr. Ich war 'bedient' und hatte beide wieder von der Platte
entfernt.

So sieht das bei mir aus, wobei ich eine while-Schleife nehmen mußte,
um ein Inkrementieren zu erzwingen. Bei for wird optimiert, indem i mit
dem Endwert geladen und bis 0 gezählt wird. Da ich die Schleife in ein
ATmega-Programm gesteckt habe, werden die MOVW eingesetzt.

Nun gut, beim AVR wird man keine char feld[10000] löschen wollen
(können). Aber eine langsame Schleife wird auch nicht schneller, wenn
sie mit Inhalt gefüllt wird.

    946          void verz()
    947          {
    948          long i=0;
   \                     verz:
   \   00000000   E040                 LDI     R20,0
   \   00000002   E050                 LDI     R21,0
   \   00000004   E060                 LDI     R22,0
   \   00000006   E070                 LDI     R23,0
    949            while(i++ < 70000);
   \                     ??verz_0:
   \   00000008   018A                 MOVW    R17 : R16,R21 : R20
   \   0000000A   019B                 MOVW    R19 : R18,R23 : R22
   \   0000000C   5F4F                 SUBI    R20,255
   \   0000000E   4F5F                 SBCI    R21,255
   \   00000010   4F6F                 SBCI    R22,255
   \   00000012   4F7F                 SBCI    R23,255
   \   00000014   3700                 CPI     R16,112
   \   00000016   4111                 SBCI    R17,17
   \   00000018   4021                 SBCI    R18,1
   \   0000001A   4030                 SBCI    R19,0
   \   0000001C   F3AC                 BRLT    ??verz_0
    950          }
   \   0000001E   9508                 RET

Wenn Ihr Lust habt, ein reales Programm zu vergleichen, hier eine
Vorgabe. http://www.mino-elektronik.de/fmeter/fm_software.htm
Wenn alles gut geht, läuft es auf einem 2313.

von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Da ich noch einen 'alten' Compiler wiedergefunden hatte (ImageC), habe
ich in ein Demoprogramm '8515intr' die besagte Schleife eingefügt.
Das Listing besser als Anlage. Ob man auf min. Code oder max. Speed
einstellt ändert nichts an der prinzipiellen Vorgehensweise. Soll jeder
für sich bewerten, ob die Codeerzeugung in seinem Sinne und
empfehlenswert ist.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Wie schon gesagt, ich finde so eine leere Schleife völlig ungeeignet für
Compilervergleiche. Manche Compiler werden z.B. erkennen dass in der
Schleife nichts passiert und sie einfach durch i=70000 ersetzen,
teilweise "aufrollen" (so ähnlich macht es der GCC) usw.

von Michael (Gast)


Lesenswert?

Andreas:
Hast Du vielleicht mein o.g. Programm durch AVRGCC 'mal compiliert ?
Das würde mich interessieren und doch auch mehr zeigen.

Natürlich ist eine Bewertung eines Compilats eine andere Sache, aber
irgendwo muß man doch versuchen, eine Bewertung anzusetzen. Oder ist
und bleibt das ein Tabu ?

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hi

habs eben mal probiert.
Nachdem ich den AVRGCC dann davon überzeugen konnte das Ding mit
diversen Warnings zu kompilieren warf er eine Codegröße von etwa 5700
Byte aus. War aber bei der Verwendung von float als Datentyp zu
erwarten. Da ist der AVRGCC AFAIK noch nicht besonders gut optimiert.
Außerdem hab ich das flash als Speicherort einfach entfernt und die
Variablen somit ins RAM verlagert. Im Anhang mal die Datei die mit ein
paar warnings vom GCC compiliert wird.

Matthias

von Michael (Gast)


Lesenswert?

Danke Matthias, obwohl die Größe etwas heftig ist. In wager Erinnerung
ist mir bei ImageC so ca. 2,5K, bei CodeV etwas weniger.

GCC habe ich sonst bei 68K und H8S eingesetzt; dort sieht der Code sehr
gut aus und ist geschickt optimiert. Die 8-Bitter sind eben etwas
anders zu handhaben als die dickeren µPs.

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hi

könntest du mal das angehängte Programm (auch eine Art Frequenzzähler)
durch den IAR jagen?

Matthias

von Andreas S. (andreas) (Admin) Benutzerseite


Angehängte Dateien:

Lesenswert?

@Michael: mit diesem Code misst man wohl weniger die Optimierung des
Compilers als die Größe der Float-Bibliothek. Ungelinkt braucht das
Programm 1214 Byte.

@Matthias: leider fehlt zum Kompilieren die code.h.

Wo wir gerade so schön am Compiler-Vergleichen sind: im Anhang ist das
nächste Testobjekt. Bitte nur kompilieren, nicht linken (Option -c beim
gcc).

von Andreas S. (andreas) (Admin) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ergebnis

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hi

@Andreas
du meinst die tools.h

Matthias

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Natürlich (wie komm ich nur auf "code")?

Hier ergibt das Programm 1304 Byte.

von Matthias (Gast)


Lesenswert?

Hi

was zu erwarten war. Sind bei mir auch genau 1304 Byte. (aktuelle
WINAVR) Merkwürdigerweise braucht der 3.3er GCC den ich gestern unter
Linux compiliert hab ein paar Byte mehr.

Matthias

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Hast du den aktuellen Snapshop runtergeladen oder den 3.3 Release?
Meinen habe ich heute aus der aktuellsten Version kompiliert.

von Matthias (Gast)


Lesenswert?

Hi

mit dem aktuellen Snapshot (gcc 3.3 vom 21.7.2003) sind es ganau 4 Byte
mehr als mit dem WINAVR. Kann das evtl. an einer anderen avrlibc
liegen?

avr-libc-20030512cvs.tar.gz

Matthias

von Michael (Gast)


Angehängte Dateien:

Lesenswert?

So, Matthias zuerst.
Die BIT0_POS +++ habe ich einfach nur nach Gutdünken definiert.
eeprom_read + eeprom_write habe ich nur als external deklariert und
nicht eingefügt und nichts gelinkt. Dafür alles auf max. speed für
einen 2313 eingestellt.
Ohne zu linken erzeugt meine Quelle fm.c bei mir 1022 Byte.

Ich finde es angenehm und würde es weiter begrüßen, die vorliegenden
Beispiele ohne Hickhack und Geschrei zu behandeln. Es ist viel Aufwand,
wenn sich jeder immer alle Demos für eigene Versuche installieren muß.

Daß AVRGCC soviel 'fließenden' Code dazulinkt, ist merkwürdig. Es
werden nur FMUL + FDIV gebraucht. Offensichtlich ist die Bibliothek zu
'grob' angelegt. Bei dickeren ATmegas ist das in der Regel belanglos.

von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Andreas:
Anbei das Ergebnis zu dbg.c. Die erweiterten Befehle zu ATmega sind
nicht aktiviert; wenn doch, dann werden es zwei Byte weniger (MOVW bei
gcd_3:)

Vielleicht hat Crazy Horse noch etwas compiliert.

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.