So, mein Werk der letzten Woche ist fertig: http://www.mikrocontroller.net/articles/PIC_C-Compilervergleich Ich hab einen Vergleich von gängigen C-Compiler gemacht und hoffe, dass es den einen oder anderen interessiert oder jemand evtl. konstruktive Kritik hat. Einiges steht im Artikel. Z.B. auch der Grund, weshalb ich diesen Vergleich gemacht habe, nämlich um endlich mal Klarheit darüber zu haben, ob die Optimierungsbegrenzung des Compilers von Microchip in der freien Version so krass ist, wie manche/viele (aber eben nicht alle) sagen. Meine Ergebnisse wollte ich hier einfach mal Veröffentlichen, auch wenn es manch einer vielleicht für Sinnlos erachtet. MFG Michael S.
Ich fände den Vergleich mit einem typischen Mikrocontrollerprogramm ohne Fließkommazahlen interessanter. Also ein Programm mit Tasterentprellung, LCD, UART, SPI-Sensoren etc.. Es muss ja nichts sinnvolles machen, sondern nur ein paar Funktionen aus (compilerunabhängige) Bibliotheken aufrufen. Denn so ist der SDCC im Prinzip gar nicht berücksichtigt und einen guten Teil der unterschiedlichen Codegröße dürften die unterschiedlichen Floating-Point-Libs ausmachen, die man auf typischen uC-Anwendungen gar nicht braucht.
Da hast du natürlich irgendwo Recht. Ich werde heute mal gucken, was ich da noch tun kann. Evtl auch ein fertiges Projekt von mir. Auf der anderen Seite wollte ich die Kompiler so nehmen wie sie sind. Es läd sich ja keiner verschiedene Compiler runter und kopiert sich die Bibliotheken zusammen. Und ansich finde ich, auch wenn man es nur für jedes 20. Projekt braucht, sollte ein kompiler mit double klarkommen. Oder mit globalen Variablen.
Nein. Ich war der Meinung und habe es irgendwo gelesen, dass die XC-Compiler die C-Compiler abgelöst haben. Also C32 ist jetzt XC32, C30 ist jetzt XC16 und C18 + der Hi-Tech C Compiler für PIC12/16/18 ist jetzt XC8. Lieg ich da falsch? Da werde ich nochmal gucken. Ich hatte sie vorher mit in der Liste drin, doch als ich im Internet gelesen habe, dass sich quasi nur der Name geändert hat, hab ich sie rausgeworfen. http://www.microchipdirect.com/ProductSearch.aspx?Keywords=SW006012 Hier steht auch: > Microchip highly recommends the MPLAB XC16 Standard > Compiler (SW006022-1) for new designs.
Michael Skropski schrieb: > Nein. Ich war der Meinung und habe es irgendwo gelesen, dass die > XC-Compiler die C-Compiler abgelöst haben. Wußte ich noch gar nicht, danke!
Ich hab mir mal den C30-Compiler runtergeladen und es nimmt sich ansich nichts. +- 10 Byte an Code-Größe gegenüber dem XC16. Ich werde nun einen Code schreiben, der ein paar Module benutzt. Ich denke so an ADC Einlesen und via I²C in ein EEPROM. Bei einem Knopfdruck dann wieder lesen und auf nem Standard LCD anzeigen. Alles in eine Datei, dann kann man es leichter anpassen und braucht nur einmal Strg+A, Strg+C und Strg+V machen ;)
Die XC-Compiler werden vor allen in Verbindung mit MPLABX beworben. Den C18 gibt es auch noch immer, aktuelles Release ist 3.44 (26.11.2012) http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010014
xfr schrieb: > Ich fände den Vergleich mit einem typischen Mikrocontrollerprogramm ohne > Fließkommazahlen interessanter. Ach nö. So ein Vergleich zeigt wenigstens auch, ob und wie gut so ein Compiler für echte Aufgaben in der Meßtechnik geeignet ist. Ich brauche GK auf dem PIC jedenfalls regelmäßig. Hier mal ein Beispiel zum Vergleich: Meine GK-Routinen (4 Grundrechenarten, single = 32 Bit) für die PIC16Fxxx sind zusammen 392 Codeworte lang, die Konverter (long-->float, float-->Text) nochmal 170 Codeworte. W.S.
Michael Skropski schrieb: > Ich werde nun einen Code schreiben, der ein paar Module benutzt. Ich > denke so an ADC Einlesen und via I²C in ein EEPROM. Bei einem Knopfdruck > dann wieder lesen und auf nem Standard LCD anzeigen. Alles in eine > Datei, dann kann man es leichter anpassen und braucht nur einmal Strg+A, > Strg+C und Strg+V machen ;) Und ruhig auch ein paar Berechnungen mit den Werten durchführen. Also z.B. ADC-Wert umskalieren mit Cast auf uint32_t und Division. Einzelne Bytes aus uint32_t-Werten extrahieren (mit Shift und Bitmaske) und ins EEPROM schreiben. Und vielleicht kleinere Algorithmen wie Daten per binärer Suche aus einer Lookup-Tabelle holen oder Bitfelder um 90° drehen (gabs kürzlich nen Thread zu). Also eben typische Dinge, die ein Mikrocontroller erledigen muss. Die Testfunktionen mit großem Optimierungspotenzial aus dem ersten Test kannst Du ja auch noch mit reinpacken (ohne Float). Um wirklich beurteilen zu können, wie gut der Compiler gearbeitet hat, müsste man natürlich auch noch die Ausführungsgeschwindigkeit berücksichtigen und sich anschauen, wie effizient die einzelnen Algorithmen eigentlich übersetzt worden sind. Aber als grobe Hausnummer ist so ein Test, denke ich, trotzdem ganz interessant. Die Optimierung muss natürlich immer auf Codegröße gestellt sein, sofern man die Wahl hat.
Vergleiche mit Fliesskommarechnung beinhalten die Grösse der dafür nötigen Runtime Libs. Eine Aussage über die Grösse des eigentlichen Codes wird dadurch erheblich verfälscht. Bei eher kleinem Textcode überwiegen dann u.U. die Kosten der Libs.
Michael Skropski schrieb: > Ich hab einen Vergleich von gängigen C-Compiler gemacht und hoffe, dass > es den einen oder anderen interessiert oder jemand evtl. konstruktive > Kritik hat. Vielen Dank für diese tolle Arbeit, sieht Klasse aus. DFer Mikroe C compiler kostet übrigens 250 USD, ausser wenn man ein DevBoard dazu kauft
Zunächst einmal vielen Dank für diese gute Arbeit und den damit verbundenen Aufwand; mein Respekt ! Die "Hausnummer" eines oder mehrerer Testroutinen, gar mit floats, sind da höchstens soweit hilfreich wie der KFZ-Normfahrzyklus und -Verbrauch bei Autos. Also Käse für die Wirklichkeit. Im richtigen embedded Bereich hat man es z.B. mit Timern, mit A/D Wandlungen, Bedienung von (seriellen) Schnittstellen etc. zu tun. Vor allem hierbei auch mit Interrupts. Die Einstellung(en) des/der A/D Wandlers, Wandlungszeit, insbesondere die Softwarestruktur mit den Interrupts etc., das macht dann ganz viel aus. I.d.R. ist diese SW-Gesamtstruktur entscheidend. Als Negativbeispiel siehe z.B. die immerwiederkommenden Anfängerfehler (hier im Forum) wo jemand serielle Schnittstellen mit 1200 Baud per Polling bedient oder Warteschleifen "wait_100ms" in SW mit auch noch gesperrtem Interrupts baut. Das GIGO Problem ist die Ursache http://de.wikipedia.org/wiki/GIGO Auch die Aussage >Die Optimierung muss natürlich immer >auf Codegröße gestellt sein ist hier i.d.R. eben genau falsch ! Denn eine auf codesize durchgeführte Optimierung führt z.B. dazu, daß der Compiler bereits kleine Codeabschnitte mit 5-8 Bytes als Unterprogramm anlegt und "Call" Aufruf dahin macht. Auch wenn diese 5-Byte-Abschnitte Teile ganz unterschiedlicher einzelner Funktionen sind! Eine Katastrophe für die Ausführungsgeschwindigkeit und Performance ist die Folge. Also das Gegenteil dessen, was man üblicherweise über #pragma inline explizit wünscht. Die Verwendung gar von float im embedded Bereich ist sowieso tabu. Hilfreich mag das für die Leute sein die mit Arduino arbeiten. Gruss
Erich schrieb: > Die Verwendung gar von float im embedded Bereich ist sowieso tabu. > Hilfreich mag das für die Leute sein die mit Arduino arbeiten. Zwei Aussagen die man so als, mal vornehm ausgedrückt, "unzutreffend" bezeichnen kann.
vielen dank für die arbeit! bezüglich der laufzeit messen mache ich das so, dass ich ein pin toggle und mit dem osci die zeit messe; zwar primitiv aber realitätssicher :-)
Master Snowman schrieb: > bezüglich der laufzeit messen mache ich das > so, dass ich ein pin toggle und mit dem osci die zeit messe; zwar > primitiv aber realitätssicher :-) Wie das? Ein reiner Pin Toggle sollte doch auf allen Compilern in die gleichen Befehle übersetzt werden und somit die gleiche Ausführungsgeschwindigkeit haben. An nem Bitsetz oder -löschbefehl läßt sich doch nichts hinzu- oder wegoptimieren?
Man setzt den Pin vor der zu messenden Funktion auf 1 und nach er Funktion auf 0 (oder umgekehrt). Man kann z.B. auch die Laufzeit der kompletten Hauptschleife damit messen (immer am Ende togglen).
W.S. schrieb: > xfr schrieb: >> Ich fände den Vergleich mit einem typischen Mikrocontrollerprogramm ohne >> Fließkommazahlen interessanter. > > Ach nö. So ein Vergleich zeigt wenigstens auch, ob und wie gut so ein > Compiler für echte Aufgaben in der Meßtechnik geeignet ist. Ich brauche > GK auf dem PIC jedenfalls regelmäßig. Ne, er zeigt garnix, sondern verfälscht das letzte Bisschen auch noch. Die Idee mit dem Test ist vorzüglich und die Mühe bemerkenswert. Allerdings will ich von einem Compiler wissen, wie gut er von lesbarem C-Code zu schnellem Assembly kommt. Das gilt insbesondere für den Embedded-Bereich. Das kann ein Compiler aber nur beweisen, wenn man ihn z.B. auf umfangreiche Algorithmen loslässt oder wenigstens auf µC-typische Aufgaben. Programmbibliotheken benchmarkt man anschließend erstmal separat. Denn dann wirds interessant, wie groß die sind und wie schnell. > Hier mal ein Beispiel zum Vergleich: Meine GK-Routinen (4 > Grundrechenarten, single = 32 Bit) für die PIC16Fxxx sind zusammen 392 > Codeworte lang, die Konverter (long-->float, float-->Text) nochmal 170 > Codeworte. Das ist jetzt unheimlich repräsentativ. Nein ernsthaft, es ist ziemlich witzlos, etwas stilisiert herumzurechnen und dann zu glauben, man könnte daran einen Compiler bewerten. In dem Testquelltext im Artikel ist ja praktisch garnichts, wo ein guter Compiler zur Optimierung überhaupt ansetzen könnte! Und nein, solche Dinge wie ungenutzte Variablen/Funktionen herauszuwerfen, die waren vielleicht vor 15 Jahren mal ganz toll, als man Pithole-Optimierer gebaut hat. Für ne aktuelle Buildchain wär das aber mal grad ein K.O.-Kriterium, wenn sie sowas nicht erkennt.
Master Snowman schrieb: > vielen dank für die arbeit! bezüglich der laufzeit messen mache ich das > so, dass ich ein pin toggle und mit dem osci die zeit messe; zwar > primitiv aber realitätssicher :-) Das stimmt. Ich werde das dann für die 8bitter mal probieren, denn die 16/32bit PICs hab ich nicht hier. Es mag sein, dass viele Programme nichts mit Kommazahlen zutun haben, doch als Beispiel ein Programm, dass die Leistung ausrechnen soll. Ein ADC-Wert ist die Spannung und einer ist die Spannung über einen Shunt. Dann muss aus beiden der Wert (Float/Double) errechnet werden und dann multipliziert werden. Oder U²/R, wo man dann die pow-Funktion braucht. Und da man ja den Compiler meist so nimmt, wie man ihn kauft/läd, nimmt man ja die eingebauten Funktionen und nimmt nicht einzelne Funktionen anderer Compiler. So hab ich mir das jedenfalls gedacht. Ein paar Werte in Register schreiben, (Warte)Schleifen durchlaufen... Das sollte ja schon fast gleich aussehen. Daher hab ich mir etwas ausgedacht, was der Compiler wegoptimieren kann. Und ich glaube fast jeder Compiler hat beide arrays, die die gleichen Waren, drinbehalten. Ok, die Werte sind änderbar, aber die Werte werden nicht verändert. Das mit der nichtbenutzten Funktion und Array war einmal, um es komplett zu haben und um zu gucken, ob sich das zwischen Frei-Version und Voll-Version ändert. Sven P. schrieb: > Allerdings will ich von einem Compiler wissen, wie gut er von lesbarem > C-Code zu schnellem Assembly kommt. Das kommt als nächstes. Ich hab mal ein Programm von mir genommen, dass Sachen aus dem EEPROM ließt und schreibt, die PWM ändert und Taster abfragt. Das ganze ist schon am Laufen: Ein Backgroundlicht, das über Taster eingestellt werden kann. Also wie hell welche Farbe sein soll. Dort muss man aber heftig anpassen zwischen den Compilern. Z.B. zeigt er bei XC8 die read/write Funktionen vom EEPROM als Falsch an, genauso wie die __delay_ms() Funktion, obwohl er es Fehlerfrei Compiliert. Beim PIC-C Compiler von CCS bin ich am gucken, wie man die FSR beschreibt. Und ich finde das heißt schon was, wenn man das nicht auf den Ersten Blick in der Hilfe zeigt. PS: Ich nehme natürlich auch gerne fertige Scripte von euch ;)
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.