Ich habe ein LCD an einen mega8 angeschlossen. Die 8bit Daten zum LCD sind an PortB angeschlossen. Da ich den UART brauche, habe ich D0-1 an PortB4 und PortB5 angeschlossen. Gebe ich jetzt die 8 bit Daten aus, würde ich in Assembler warscheinlich einfach swap verwenden, um die Bits 0&1 auf Stelle 4&5 zu bekommen, oder was auch gehen würde, wäre mul. Wiso macht WinAVR das ganze aber mit Shifts ? Das dauert mindestens 5x solange... Kann man WinAVR irgendwie dazu bringen swap zu verwenden ? PORTD=byte; PORTB=byte*16; 2463 0180 C2BB out 50-0x20,r28 2464 .LM104: 2465 0182 8C2F mov r24,r28 2466 0184 9927 clr r25 2467 0186 34E0 ldi r19,4 2468 0188 880F 1: lsl r24 2469 018a 991F rol r25 2470 018c 3A95 dec r19 2471 018e E1F7 brne 1b 2472 0190 88BB out 56-0x20,r24
Hallo, die einfachste Methode, den Compiler genau das machen zu lassen, was man will, ist inline assembly. Dann passiert genau das was Du schreibst - wenn man weiß was man will und was man tut ist das eine gute Sache. In Deinem Fall wäre es auch eine Möglichkeit, dem Herrn Compiler genauer zu erklären, welche Bits Du überhaupt auf dem Port sehen willst. a la : PORTD |= (byte & 0x03) << 4; Schau doch einfach ma, was er dann macht - vielleicht ja das Richtige ;-) MfG, Daniel.
Ja, das ist so. Der AVR-GCC hat eine extreme 16Bit-Lastigkeit. D.h. er macht viele 8Bit-Rechnungen erstmal in 16Bit um dann das High-Byte wieder wegzuschmeißen. Besonders unangenehm fällt das bei switch-Anweisungen und beim Test auf Bit 0 auf (Bit 1..7 werden optimal mit SBRS getestet). Solange das keinen der Leute nervt, die Compiler bauen können, ist da auch keine Abhilfe in Sicht. Was mich auch wundert ist, daß bei jeder neuen WINAVR-Version der erzeugte Code immer größer wird. Scheint also so, daß Codeoptimierungen kein Bestandteil neuerer Versionen sind, sondern nur Bug-Fixes (falscher Code) und dabei manche Optimierungen wieder wegfallen. Peter
> Solange das keinen der Leute nervt, die Compiler bauen können, ist > da auch keine Abhilfe in Sicht. Nun, wie bei allem: man kan alles lernen. Auch GCC scheint nicht so schwer zu lernen zu sein, einige Leute haben das bewiesen. Sonst gäbe es keinen AVR-GCC überhaupt (der ist ja nicht irgendwie ,,von den GCC-Leuten'' gemacht worden, sondern von jemandem, der gern einen GCC auf AVR haben wollte). Wer die einschlägigen Mailinglisten mal verfolgt (die meisten ernsthaften Entwickler meiden Webforen, wo's nur geht, weil sie im Vergleich zu Mailinglisten oder Newsgruppen eigentlich nur Nachteile haben), kann man z. B. sehen, dass Björn Haase gerade einiges gemacht hat. > Was mich auch wundert ist, daß bei jeder neuen WINAVR-Version der > erzeugte Code immer größer wird. Was mich wundert ist, dass Peters Aussagen immer unsinniger werden. Merkst du, dass Pauschalisierungen hinken? Dmitry Xmelov (sp?) hat mal ein paar Analysen veröffentlicht, welcher Code mit welchen Compilerversionen und -optionen besser oder schlechter optimiert worden ist. Es gibt eine gewisse Tendenz, dass bei AVR tatsächlich die Optimierung nachgelassen hat (was im Sinne von GCC durchaus als `regression' gilt und damit mehr Priorität beim Bugfixing geniest als feature fixes -- so man die Bugs denn auch berichtet), aber es gibt durchaus auch Dinge, die mit neuen Versionen besser geworden sind. > Scheint also so, daß Codeoptimierungen kein Bestandteil neuerer > Versionen sind, sondern nur Bug-Fixes (falscher Code) und dabei > manche Optimierungen wieder wegfallen. Korrekter Code wäre natürlich ohnehin wichtiger als gut optmierter Code. Anyway, mein persönlicher Eindruck: die 3.4er Versionen vom GCC sind vor allem so schnell rausgefeuert worden, weil die AMD64-Plattform (alias x86_64) massiv Priorität genossen hat. Die war wohl bei 3.3 noch total buggy, aber der Compiler wurde dringlichst benötigt, da die Prozessoren nun einmal in Massen da sind und auch benutzt werden möchten. Offenbar sind bei diesen Hobeleien zuweilen Späne gefallen, und (eher unbeabsichtigt) andere Targets als die mainstream i386 und amd64 in die Rubrik ,,Pessimierung'' reingerutscht. Krassestes Beispiel war, dass ein bestimmtes Stück Code mit dem C++-Compiler drastisch schlechter compiliert worden ist als mit dem C-Compiler. Gleicher Quellcode unter einem GCC 3.3.x ergab (nahezu) identischen Assemblercode für beide Compiler.
Je mehr ich mit WinAVR programmiere, desto häufiger überlege ich, ob ich wirklich ein AVR brauche oder ob das ganze nicht auch in Assembler auf einem 8051 läuft... @Daniel Der Tip war genau richtig ! Deine Lösung wird zu 2438 016e C2BB out 50-0x20,r28 2439 .LM101: 2440 0170 C370 andi r28,lo8(3) 2441 0172 C295 swap r28 2442 0174 C07F andi r28,0xf0 2443 0176 C8BB out 56-0x20,r28 2444 .LM102: Es ist echt unglaublich, was ein oftmals komplizierterer Code an Vereinfachung bringen kann. Wobei der Compiler trotzdem verdammt dumm ist: Wenn er vor dem swap bits 4-7 löscht, dann bräuchte er hinterher nicht nochmal bits 0-3 zu löschen...
Peter: > Was mich auch wundert ist, daß bei jeder neuen WINAVR-Version der > erzeugte Code immer größer wird. Jörg: > Es gibt eine gewisse Tendenz, dass > bei AVR tatsächlich die Optimierung nachgelassen hat Sorry, aber für mich ist beides das gleiche, nur mit anderen Worten. Als Optimierung nehme ich immer -Os Wenn ich das andere richtig verstehe, ich kann also ruhig noch die alte Version nehmen, wenn ich kein 64Bit-OS benutze ? Peter
P.S.: Die Unterschiede sind natürlich nur gering (1,5%): C:\AVR\WINAVR\BIN>avr-gcc.exe -dumpversion 3.3.2 D:\WORK\AVR_C\PU\5KV>a.bat text data bss dec hex filename 3226 20 351 3597 e0d test.out C:\AVR\WINAVR\BIN>avr-gcc.exe -dumpversion 3.4.3 D:\WORK\AVR_C\PU\5KV>a.bat I2C.C:49: warning: `i2c_interrupt' appears to be a misspelled signal handler text data bss dec hex filename 3278 20 351 3649 e41 test.out Peter
> Wenn ich das andere richtig verstehe, ich kann also ruhig noch die > alte Version nehmen, wenn ich kein 64Bit-OS benutze ? Das verstehe ich nun überhaupt nicht. Du kannst natürlich alte Versionen benutzen, aber du riskierst dann eben auch, dass du erstens Bugs erliegst, die mittlerweile schon repariert sind, und zweitens kann es gut auch sein, dass du (je nach Anwendungsfall) mal die eine oder andere verbesserte Optimierung verpasst. Andererseits: das letzte Stück herumfeilen muss man ja eigentlich nur dann, wenn der gerade genutzte Prozessor kurz vor voll ist oder man dadurch in der Produktion den nächstkleineren benutzen könnte. ,,Nur so aus Sport'' wüsste ich besseres, um mir meine Zeit zu vertreiben. ;-)
> Je mehr ich mit WinAVR programmiere, desto häufiger überlege ich, ob > ich wirklich ein AVR brauche oder ob das ganze nicht auch in > Assembler auf einem 8051 läuft... Die Frage ist halt die Effizienz der Codeentwicklung. Für paar wenige Zeilen ist das sicher egal, aber mit zunehmender Größe des Projekts hast du mit dem Assemblerklumpen eben immer mehr Wartungsaufwand. Das kann bei einem größeren Projekt gut auf das 10fache anwachsen.
Ach, da hilft doch nur eins: sich nen vernünftigen Compiler aussuchen und nicht so ein freies Produkt, wo jeder mal irgendwie dran rumwerkelt und zum Schluß doch nichts sinnvolles bei rumkommt. Eben so, wie auch bei Linux und Konsorten. Ist doch alles nur eine rießen Baustelle ohne richtigen Nutzen :) LOL
> Ach, da hilft doch nur eins: sich nen vernünftigen Compiler > aussuchen und nicht so ein freies Produkt, wo jeder mal irgendwie > dran rumwerkelt und zum Schluß doch nichts sinnvolles bei rumkommt. Klar. Was soll der Geiz, scheiß auf's neue Auto, lieber für dasselbe Geld einen IAR EW gekauft. :-)
ich nutze derzeit sowohl linux als auch windows.. und muss zugeben teilweise sind die linux-tools etwas gewöhnungsbedürftig doch bieten sie teilweise features die du bei kommerziellen teilen vermissen wirst wenn du sie gewohnt bist ;) aja es gibt derzeit nur einen compiler (meines wissens) der auf der intel plattform schnelleren/kleineren oder wie auch immmer "besseren" code macht wie der gcc.. das wäre der intel eigene... und zum thema baustelle.. unter linux gibts nur neue stable-kernels wenn die auch wirklich stable sind... ausnahme war 2.2 ... wobei ausrutscher passieren nunmal... siehe win98 ROFL ;) wenn du jetzt meinst 98 war eine ausnahme..warum gibts von xp ein sp, dass im prinzip alles wirklich wichtige umdreht??? oder ein 98, das komplett "neu" war??? ähnliches gibts auch bei 2003.. nur bei 2k ist mir nix bekannt... anmerken möchte ich noch, dass im prinzip jedes betriebsystem eine baustelle darstellt.... eigentlich jede anwendung sogar.. es gäbe immer was zu fixen,... soo jetzt noch schnell was zum topic G wie weit ist der c++ compiler für den avr eigentlich schon optimiert bzw wie weit reicht der support dafür??? ;) ich steh einfach auf oop.. und bei 128k flash und 64k ram geht das doch ohne probs ;) 73
Hi @Helmut Wer hat dich eigentlich aus dem Heiseforum rausgelassen? Oder bist du sogar aus dag° entwischt? SCNR Matthias
> Klar. Was soll der Geiz, scheiß auf's neue Auto, lieber für > dasselbe Geld einen IAR EW gekauft. :-) Naja, wollen wir mal nicht übertreiben. Der ICCAVR von Imagecraft kostet 780 Dollar und der ist sein Geld wert. Zwar ist er auch nicht perfekt, dennoch erzeugt er kleinen und schnellen Code und er ist schnell durchschaubar (keine ewig langen Textdateien), da z. B. Einstellungen für Bootloaderapplikationen bequem per Menu erfolgen. Und man hat eine überschaubare Installation und nicht tausende (?) Dateien nur für ein Compiler. Es gibt auch keine Probleme, die durch Updates entstehen. Halt einfach ein gut durchdachtes Produkt. Und wem die integrierte IDE zu grauenvoll ist, kann jederzeit fürs editieren edit.com (oder Emacs; pfui bah!) benutzen und in der Console die Kommandozeilentools des Compilers. Aber jedem das seine :) Übrigens bin ich nicht Mitarbeiter von Imagecraft. Dies nur für den Fall, daß mir Schleichwerbung vorgeworfen wird, was hier im Forum ja schon öfter mal vorkommt.
@Matthias > Wer hat dich eigentlich aus dem Heiseforum rausgelassen? > Oder bist du sogar aus dag° entwischt? Hehe, du scheinst da ja Stammgast zu sein.
Nu ja, ganz davon abgesehen, dass mir ein Windowscompiler einfach mal überhaupt nüscht nützt, hast du mal für mehr als "Hello world"- Projekte die Codegrößenvergleiche gesehen? Ganz ernsthaft, für den GCC sehe ich lediglich den IAR als Alternative (der kostet aber wirklich so viel wie'n gebrauchtes Auto, und ohne Windows kann ich ihn trotzdem nicht nehmen).
> Nu ja, ganz davon abgesehen, dass mir ein Windowscompiler > einfach mal überhaupt nüscht nützt Ok, ICC ist natürlich wirklich nur für Windowsnutzer tauglich :) Die Codegrößenvergleiche habe ich in der Tat gesehen weil ich mir selbst mal die Mühe gemacht habe, ein ICCAVR-Projekt auf GCC zu portieren. Es handelte sich um eine GPS-Anwendung mit aufwendiger Menüsteuerung (grafisches Display). ICC erzeugte 61kByte Code mit Optimierung, der GCC machte daraus 79kByte mit Optimierung. Ich hab die Sache dann in die Tonne getreten, denn hätte ich GCC weiter benutzt, so wäre ein größerer (und damit teuerer) Controller erforderlich gewesen.
Ich fands auch sehr extrem, bin dem Problem aber auch nicht näher nachgegangen, denn ich benutze ja eigentlich ICC. GCC wäre halt ne Alternative, weil Upgrades kein Geld kosten.
oder du hast nicht richtig portiert.. man muss eben wissen was ein compiler für code erwartet damit er damit was anfangen kann... und da der gcc 16bit lastig ist kann ich mir das sehr gut vorstellen... zumal du da haufenweise bit operationen drinnen haben wirst.. da muss man sich beim gcc was überlegen damit der code klein und schnell wird... aja welche optimierung hast du "damals" genommen ?? Os wäre gut gewesen.. O2 auch aber O3 (höchste optimierungsstufe) macht dir größeren code wie Os !!! siehe doku.. damit ließe sich das schon erklären... 73
Leute Leute, Ich hab doch nicht über den WINAVR gemeckert. Das mit der 16Bit-Lastigkeit und dem größer werdenden Code sind reine Feststellungen, mehr nicht. Und seit dem Mega8 und mit dem Mega168 habe ich auch genügend Reserven. Ein Vergleich mit IAR / ICC wäre natürlich mal interessant. Worin der WINAVR unschlagbar ist, ist natürlich, daß ich ihn auf allen PCs (Werkstatt, Büro, Home, Notebook) laufen lassen kann ohne 4 Lizenzen kaufen zu müssen oder ständig mit nem Dongle durch die Gegend zu rennen. Peter
> Ein Vergleich mit IAR / ICC wäre natürlich mal interessant.
IAR hat eine Menge niedlicher netter kleiner Optimierungen, die
in der Summe schon nochmal 10 % oder so ausmachen, je nach Quellcode
natürlich. Man merkt ihm einfach an, dass er ein auf Controller
gut zugeschnittener Compiler ist, anders als GCC, der ja aus einer
völlig anderen Welt kommt.
du verkennst die eigentlichen vorteile ;) 1: du kannst am schlepp linux in der werkstatt win95 und in der fa xp haben und immer den geleichen compiler verwenden 2: du kannst mit deinen avrs spielen und wenns dich überkommpt schnellmal einen arm ausprobieren mit den gleichen compiler,ide,... 3: du musst nicht hoffen, dass auf deinem zukünftigen os dein compiler noch rennt... und 4: du hast den code ;) 73
So jetzt muss auch noch meine Senf dazu geben. Es greift zu kurz, wenn man einen Compiler nur nach Laufzeit und Resourcenbedarf beurteilt. Ich halte den gcc (z.Zt. Version 3.3.5, i386, ARM7, AVR) für einen der besten Compiler mit denen ich bisher gearbeitet habe. ICC hatte ich auch mal für einen Monat im Test und der ist ok. Man bekommt sehr schnell sein Programm auf die Beine. Aber die tollen Tools/Menues zur Configuration von Baudrate, Timer, etc. nageln dich auch ziemlich auf diesen Compiler fest. Besser finde ich da eine universelle Lösung die mir per Makro/Präprozessor die passenden Einstellungen für UART, Timer, etc. aus den defines für Baudrate und CPU-Clock ableiten. Und zum Finden von Informationen in Dokus und Sourcen gibt es Suchfunktionen. IAR habe ich vor Urzeiten mal auf einem H8/500 laufen gehabt und fand ihn gut. Vor einem Jahr habe ich den IAR für den PIC18 getestet und konnte keine Schwächen finden. Aber ein kurzer Test ist noch kein komplettes Projekt. Auf jeden Fall hat der Compiler einen guten Ruf. Es gibt nach meiner Einschätzung einen Menge Compiler die deutlich schlechter sind als der gcc. Und der gcc könnte durch unserer Mithilfe sogar noch etwas besser werden.
Manche Optimierungen anderer Compiler werden durch Verletzung von ANSI-Definitionen erkauft. So habe ich auch schon mal 8-bit "int" als Standard gesehen. ANSI verlangt 16bit. Oder arithmetische Operationen werden nur dann 16bittig ausgeführt, wenn mindestens einer der Operanden 16bittig ist. ANSI hingegen verlangt, dass das Erghebnis so ist, als wäre sie immer mindestens 16bittig ausgeführt worden - was er tatsächlich macht ist egal. Das macht beispielsweise bei uint8_t a, b; if (a + 1 > b) einen Unterschied. Bei a=255 ist es hier absolut nicht egal, ob das in 8bit oder 16bit gerechnet wird.
Ich hab mal in einer meiner Dateien nachgesehen und dort wird sehrwohl swap verwendet. Auszug aus der lst-Datei. void lcd_data_command(uint8_t signal) { 360: 1f 93 push r17 362: 18 2f mov r17, r24 /* delete the data port pins */ /* put high nibble to data port */ LCD_DATA_PORT = (LCD_DATA_PORT & ~LCD_DATA_MASK) | (signal >> 4); 364: 88 b3 in r24, 0x18 ; 24 366: 80 7f andi r24, 0xF0 ; 240 368: 91 2f mov r25, r17 36a: 92 95 swap r25 36c: 9f 70 andi r25, 0x0F ; 15 36e: 89 2b or r24, r25 370: 88 bb out 0x18, r24 ; 24 lcd_enable(); 372: ed df rcall .-38 ; 0x34e /* delete the data port pins *//* put low nibble to data port */ LCD_DATA_PORT = (LCD_DATA_PORT & ~LCD_DATA_MASK) | (signal & 0x0f); 374: 88 b3 in r24, 0x18 ; 24 376: 80 7f andi r24, 0xF0 ; 240 378: 1f 70 andi r17, 0x0F ; 15 37a: 81 2b or r24, r17 37c: 88 bb out 0x18, r24 ; 24 lcd_enable(); 37e: e7 df rcall .-50 ; 0x34e 380: 8c e5 ldi r24, 0x5C ; 92 382: 00 00 nop 384: 81 50 subi r24, 0x01 ; 1 386: e9 f7 brne .-6 ; 0x382 /* the lcd-controller needs some execution time */ lcd_delay_50us(); } 388: 1f 91 pop r17 38a: 08 95 ret
OK, nie war vielleicht etwas übertrieben, aber swap/mul wird seltener angewendet als es möglich und sinnvoll wäre. In meinen LCD Routinen kam es z.B. garnicht vor, ehe ich den Code etwas anpasst habe.
wie ich oben schon so schän erwähnt habe... > man muss eben wissen was ein > compiler für code erwartet damit er damit was anfangen kann... und das gilt für jeden compiler.. der kann ja nicht ahnen was du dir da vorstellst was rauskommen soll.. 73
Hi, ich hab den Thread hier mit etwas Erstaunen gelesen und frage mich grad ernsthaft ob WinAVR die Mühe wert ist. Stimmt das wirklich das so rudimentäre Befehle wie Swap und (noch schlimmer) der Hardware Multiplyer nicht unterstütz werden? Für rechenintensive Projekte ist sowas doch ne absolute Katastrophe, auch noch wenn alles, ob nötig oder nicht, erstmal in 16 Bit umgewandelt wird. Kostenlose OpenSource hin oder her, aber wenn sowas wichtiges nicht unterstützt wird kann man das doch für ernsthafte Projekte doch allen ernstes vergessen. Sollte ich irgendwas mißverstanden haben bitte ich um Entschuldigung und bitte um Aufklärung JarJar
Hi beide Befehle werden, sofern sinnvoll und möglich auch verwendet. Es kann aber durchaus mal eine Situation vorkommen in der der Compiler nicht "bemerkt" das ein swap oder mul effizienter wäre. Ich hab aber mitlerweile einige Projekte mit dem avrgcc realisiert die auch munter vor sich hin verkauft werden. IMHO kann man mit dem AVRGCC sehr ordentlich arbeiten auch ohne ständig in den ASM-Outputs rumzulesen. Matthias
Hm, wäre aber schon schön zu wissen ob die (beschrängten) Ressourcen des Controllers vernünftig ausgenutzt werden oder ob durch zu großzügigen Umgang damit wertvolle Rechenleistung weggeschmissen wird. Hab mal ein einfaches neuronales Netz programmiert. Wenn da der Code nicht optimal ist schmeißt man unendlich viel Leistung weg (es geht mir nichtmal um Programmgröße). Wenn ich schon lese das arithmetische Operationen erstmal auf 16 Bit aufgeblasen werden stellen sich meine Nackenhaare auf und alle Alarmglocken schrillen. Für 95% aller Anwendungen mag das vielleicht nicht in's Gewicht fallen, aber wenn man dann doch mal drauf angewiesen ist wüsste ich gern was Sache ist
@JarJar, ... gibt man jemandem den keinen Finger (wobei das meiner Meinung nach schon fast 9,45 Finger sind), will er gleich die ganze Hand! Ein vergleich mit Autos erklärt den menschen meist am besten um was es geht. Wer von einem VW Käfer im Gelände/Offroad die geiche Leistung erwartet wie von enem Hummer Jeep hat nun mal auf die falsche Karte gesetzt - DAFÜR IST ER NUN MAL NICHT GEBAUT. Aber man kann trotzdem ganz gut auf schlammigen Feldwegen fahren - aber eben nicht in extremem Gelände.
Sorry wenn ich Deine Meinung nicht teile. Wenn ich ein Auto fürs Gelände will kauf ich mir natürlich ein entsprechendes. Aber wenn ich einen Compiler für einen Controller will dann erwarte ich von dem Compiler (egal ob der von Porsche oder VW kommt) das der die verfügbaren Ressourcen des Controllers nutzt. Die sind ja da. Ein VW Käfe hat die Ressource "Geländeaufhänung" und "4WD" nunmal nicht damit man ins Gelände kann. Ich würde eher sagen das man das zb mit einem Satz Schraubenschlüssel vergleichen kann bei dem eine Größe fehlt. Mit dem kann man auch nur so lange arbeiten bis man mal eine Schraube bearbeiten muß für die der Schlüssel fehlt. Worum es mir geht ist das vorhandene Befehle genutzt werden undunnötige Operationen wie das unnötige Aufblasen auf 16 Bit vermieden werden. Ich rede noch gar nicht über hochintelligente Strategien um schlechten Code noch halbwegs schnell und kompakt zu machen. Keine Optimierung sondern nur die grundsätzliche Ausnutzung des vorhandenen
Nur um das klarzustellen: ich weiß wie schwierig es ist einen Compiler zu programmieren. Wenn Befehle in der Regel verwendet werden und nur in seltenen Fällen mal anders umgesetzt werden hab ich durchaus Verständnis und werde mich in dem Fall selbst um Besserung bemühen, aber Ressourcen wie Befehle, spezielle Register oder was auch immer aus Bequemlichkeit zu ignorieren find ich sch****. Ein Mikrocontroller hat begrenze Ressourcen und wenn mit denen leichtfertig umgegangen wird finde ich das weniger lustig. Wenn ich zwei 8 Bit Werte auf einem Mega8 multipliziere erwarte ich schon das da auch wirklich je 8 Bit in den Hardware Multiplyer geschoben werden und der mir einen 16 Bit Wert liefert. Aus dem was ich hier gelesen hab entnehme ich das dem nicht so ist. Korrigiert mich bitte wenn ich mich irren
Hi es werden nur die Operationen (AFAIK hauptsächlich Logik) in 16 Bit ausgeführt die laut C-Standard auch in 16 Bit ausgeführt werden müssen. Multiplikationen gehören nicht dazu. Aus while(1) { o1 = PINA; o2 = PINB; r = o1 * o2; PORTC = r & 0xFF; PORTD = (r / 256) & 0xFF; } wird o1 = PINA; 96: 99 b3 in r25, 0x19 ; 25 o2 = PINB; 98: 86 b3 in r24, 0x16 ; 22 r = o1 * o2; 9a: 98 9f mul r25, r24 9c: c0 01 movw r24, r0 9e: 11 24 eor r1, r1 PORTC = r & 0xFF; a0: 85 bb out 0x15, r24 ; 21 PORTD = (r / 256) & 0xFF; a2: 89 2f mov r24, r25 a4: 99 27 eor r25, r25 a6: 82 bb out 0x12, r24 ; 18 a8: f6 cf rjmp .-20 ; 0x96 Sicher nicht ideal (aus der Sicht eines ASM-Programmierers) aber die Multiplikation wird nicht mit 16 Bit Operanden durchgeführt. Und wenn dir die Qualität des kostenlosen Tools nicht ausreicht steht dir immer noch der Weg zum IAR-Compiler offen. Vor diesem Weg liegt halt die Brücke mit mehreren k Brückenmaut :-) Matthias
Der Compiler kostet dich nichts und liefert m.E. meist eine passable Code-Qualität ab. Optimal ist er nicht - aber GCC hat gewisse Grundvoraussetzungen an die Zielmaschine (z.B. >= 16bit ISA, hinreichende Anzahl Register) die von AVR nicht alle erfüllt werden. Übrigens auch nicht von diversen anderen GCC Targets aus dem Microcontroller-Sektor, wie 6811/12 oder R8c/M16c/M32c (die Anzahl Register ist zu gering), auch da ist die Umsetzung dementsprechend nicht optimal. Es hindert dich jedoch niemand daran, der Compiler dementsprechend umzubauen. Der Quellcode ist frei verfügbar. Andererseits hindert dich auch niemand daran, einen Compiler zu kaufen. Ich würde dir aber raten, ihn vorher auszuprobieren. Er wird deinen Ansprüchen wahrscheinlich auch nicht gerecht werden.
Ich bin kein Mensch der sich nicht von vernünftigen Argumenten überzeugen läßt ;) Ich hab ja auch gesagt: bitte korrigiert mich wenn ich falsch liege. Ich hab mich am Betreff und an einigen anderen Aussagen gestört die nicht richtig wiederlegt wurden. Anscheinend ist das weitestgehen geklärt. Ich werd mich mal damit befassen.
> Ich hab ja auch gesagt: bitte korrigiert mich wenn ich falsch liege. Kein Compiler wird wirklich das erzeugen können, was du mit der Hand als Assemblercode zimmern könntest, wenngleich heutige Compiler oft genug ganz gut an derartigen Code herankommen und ihn streckenweise auch übertreffen (weil der generierte Assemblercode dann derart schlecht lesbar ist, dass ihn selbst eingefleischte Assemblerfreaks nicht so aufschreiben würden). Der AVR-GCC dürfte nach allem, was man in diversen Forums und Mailinglisten lesen kann, durchaus drastisch im oberen Drittel der Compiler rangieren, was die Effektivität des generierten Codes betrifft. Ein wirklich guter kommerzieller Compiler, der (im Gegensatz zu GCC) von vornherein auf Microcontroller ausgerichtet ist, kann ihn andererseits auch beinahe auf jedem Gebiet übertreffen. Nach allem, was ich gehört und gelesen habe, dürfte der IAR Embedded Workbench da wohl der Einzige sein. Wie dir schon gesagt wurde, den bezahlst du nach KiloEUR -- pro Arbeitsplatz, versteht sich (nichtmal MS Terminal Server wird akzeptiert). Von anderen Hostbetriebssystemen als Windows sprechen wir natürlich dabei auch nicht. Falls du dir den circa 10fachen (für ein ansehnlich großes Projekt) Wartungsaufwand für reine Assemblerprogrammierung leisten kannst oder willst: deine Sache. Für > 10000 Stück Jahresproduktion mag das auch kommerziell angehen, wenn man vielleicht den nächstkleineren AVR benutzen kann dadurch, aber privat ist mir meine Freizeit zu schade, einen derartigen Aufwand zu treiben. Das habe ich in den letzten Jahren genau einmal gemacht (in diesem Falle mit einem PIC), danach wusste ich, dass ich im 3. Jahrtausend nicht mehr alles mit einem Assembler programmieren möchte. (Dadurch bin ich dann zu den AVRs gekommen.)
Hab doch gesagt das es jetzt ok ist. Ich hätte nur ernste Zweifel gehabt wenn wirklich grundlegende Funktionen wie der Hardware Mul nicht unterstützt würden. Hab keinen Bock mir das selber zu stricken. Wie gesagt, es ging mir nicht um nen idealen Optimizer oder 100% optimalen und fehlerfreien Code sondern nur darum das grundsätzlich erstmal alle wichtigen Funktionen verwendet werden. Mit einem Compiler der nicht immer optimalen Code erzeugt kann ich leben, aber nicht mit einem der nicht alles (wichtige) kann
Peter: > Was mich auch wundert ist, daß bei jeder neuen WINAVR-Version der > erzeugte Code immer größer wird. http://lists.gnu.org/archive/html/avr-gcc-list/2005-07/msg00182.html Man könnte beim Anblick der "Summary"-Zeile den Eindruck gewinnen, dass es bis zu 3.4.x immer besser geworden wäre und mit 4.x schlechter. ;-) Das ist das, was ich mit den Pauschalisierungen meinte...
Was ist an dem Eindruck falsch? Ich kenne die Unterschiede in den Versionen nicht. Ich habe aber schon bei anderen Compilern beobachtet das ein Programm ohne Zutun von Compilerversion zu Compilerversion größer werden kann. Einmal mußte ich das schmerzlich feststellen als ein Programm nicht mehr in nen Mega8 gepasst hat was vorher der Fall war. Ursache in dem Fall waren Bugfixes und Ergänzungen an einzelnen Funktionen
Ich hab auch mal rumgemeckert warum (in einer speziellen Funktion) der gcc4.x schlechter optimiert (Code wurde einiges größer) als der gcc3.x. Als ich aber für die Takte nachgezählt habe, wurde klar dass der Code schneller war, es war halt eine tricky-Schleifenoptimierung. Ich hab auch Funktionen die ca. 10mal so gross wurden, was aber durch -funroll-loops gewollt war, hat mir den Faktor 2 in der Geschwindigkeit der IR-Datenübertragung gebracht. Codegrösse ist bei mir nebensächlich, schnell muss er sein. @JarJar: der GCC verwendet mul und swap
Wie muss ich das umschreiben, damit swap bzw. mul verwendet wird ? LCD_port|=(LCD_port&15)|((byte&15)*16); Im Moment wird daraus ein Shift.
Ok, ist natürlich ne Frage welche Optimierung einem lieber ist, Codegröße oder Tacktzahl. Beides gleichzeitig geht halt so gut wie gar nicht. In meinem Fall (anderer Compiler) gab es gar keine Optimierungsmöglichkeiten, aber die Codegröße ist bei Updates gelegentlich angewachsen was in dem Fall wirklich an Bugfixes oder erweiterten Funktionen lag, nicht an der Änderung der Optimierungsstrategie. Wenn man sich die oben genannte Tabelle aber anschaut kann man sich schon wundern. Ich nehme mal an die vordere Zahl ist jeweils Flash, die hintere ist der Ram Bedarf. Die Version 4.0 ist beim Gesamtflash nur unwesentlich besser als als 3.2 und beim Ram sogar deutlich schlechter. Aber es ist ja auch nur eine Auswahl (vermutlich zufällig ausgesuchter) Routinen was nichts über das Gesamtergebnis der jeweiligen Programme aussagen muß. Wenn die Vergrößerungen auf Bugfixes oder andere Verbesserungen zurückzuführen sind kann denke ich jeder damit leben, es sei denn dadurch bekommt er ein Programm wirklich nicht mehr in einen Controller. Richtig bitter wird es wenn es keinen größeren Controller mehr gibt
"Richtig bitter wird es wenn es keinen größeren Controller mehr gibt" Dann hat man den Fehler schon vorher gemacht. Wer beispielsweise ein Programm auf MSP430 schreibt, das schon in der ersten produktiven Version bei 30-40KB liegt, der hat den Fehler schon bei der Auswahl des Controllers gemacht.
Bei mir macht er kein Shift (gcc 4.01, mit -O2): 4038 15be 9091 0000 lds r25,uhrneu 1836:wecker.c **** LCD_port|=(LCD_port&15)|((byte&15)*16); 4040 .LM521: 4041 15c2 28B3 in r18,56-0x20 4042 15c4 88B3 in r24,56-0x20 4043 15c6 8F70 andi r24,lo8(15) 4044 15c8 9295 swap r25 4045 15ca 907F andi r25,0xf0 4046 15cc 982B or r25,r24 4047 15ce 292B or r18,r25 4048 15d0 28BB out 56-0x20,r18
Warum? Wenn man ein Programm geschrieben hat das im Prinzip fertig ist und von allen Ressourcen in einen Mega32 passt und vielleicht noch 100-200 Bytes Luft sind, warum sollte man dann (vor allem in der Massenfertigung) einen doch etwas teureren Mega64 nehmen? Wenn man dann nur ne klitzekleine Änderung machen muß die normal keinen Einfluß auf die Programmgröße hat und das Programm auf einmal nicht mehr in den Controller passt ist man auf deutsch gesagt der Gearschte, es sei denn man hat sich die ältere Version des Compilers aufgehoben. In der Industrie wird keiner einen größeren Controller einsetzen nur um die Möglichkeit auszuschließen das das Programm aufgrund von Compileränderungen auf einmal nicht mehr reinpasst
Wenn das alles wie festgefroren ist... Aber wozu dann neu übersetzen? Oft ergeben sich mit der Zeit nicht klitzekleine Dinge. Es werden etliche neue Funktionen nachgefragt. Der Benutzerführung/Bedienung versteht bloss der Programierer, muss also umgeschrieben/erweitert werden. Usw. An sowas dachte ich. Das trifft vor allem grössere Programme - bei Kleinkram von ein paar KB Code ändert eher wenig. Ansonsten: Wirf bei einem Upgrade den alten Compiler nicht weg sondern installieren die neue Version neben der alten. Grad bei GCC ist das problemlos möglich. Ob das bei typischen Windows-Compilern mit entsprechender Verwendung der Registry auch möglich ist?
Wieso aufbehalten? Auf ftp://ftp.gnu.org/gnu/gcc/ bekommst noch alle Versionen zurück bis ins Jahr 1992 :-)
Ah, cool. Jetzt muß man nur noch nen Internetzugang haben wenn man man nen alten Compiler braucht ;) Also ich hab meistens 2-3 Versionen bei mir auf der Platte und einmal hat mir das echt geholfen weil ein Update einen Fehler in einer Funktion eingebaut hatte den es vorher nicht gab. Alte Version installiert, neu compiliert und schon lief's wieder
"In der Industrie wird keiner einen größeren Controller einsetzen" Nein, sicher nicht. Aber wenn er eine Controller-Familie auswählt, die schon jetzt knapp dran ist, also kein grösseres Modell existiert, dann hat er niedrige Kosten jetzt gegen erhebliche Umstiegskosten später eingetauscht. Kann man machen, aber man muss sich über solche Folgeeffekte dann im Klaren sein.
> LCD_port|=(LCD_port&15)|((byte&15)*16); > Im Moment wird daraus ein Shift. Vermutlich wird er davon ausgehen, dass der shift schneller wäre (was ohne hardware multiplier ja auch wirklich der Fall ist). > Wenn man sich die oben genannte Tabelle aber anschaut kann man sich > schon wundern. Ich nehme mal an die vordere Zahl ist jeweils Flash, > die hintere ist der Ram Bedarf. Die Version 4.0 ist beim Gesamtflash > nur unwesentlich besser als als 3.2 und beim Ram sogar deutlich > schlechter. 4.0 ist halt eine Entwicklerversion, ein dot-zero release eben. Wenn du den Thread mal weiterverfolgst, gibt's noch ein Followup, in dem Dmitry den 4.1-CVS mit getestet hat, der kommt wieder auf den Werten heraus, die zuvor als Bestes auftauchten. > Aber es ist ja auch nur eine Auswahl (vermutlich zufällig > ausgesuchter) Routinen was nichts über das Gesamtergebnis der > jeweiligen Programme aussagen muß. Genau so ist es. Vom ,,Gesamteindruck'' realer Applikationen her bestätigte sich nämlich (was ja zu Peters Bemerkung führte) der Trend, dass GCC 3.4.x besser als seine Vorgänger sei, durchaus gar nicht. Die Matrix zeigt aber, dass er es in einzelnen Teilen durchaus ist (nur daher hatte ich den Link gepostet). > Warum? Wenn man ein Programm geschrieben hat das im Prinzip fertig > ist und von allen Ressourcen in einen Mega32 passt und vielleicht > noch 100-200 Bytes Luft sind, warum sollte man dann (vor allem in > der Massenfertigung) einen doch etwas teureren Mega64 nehmen? Weil nach dem Gesetz von Murphy der schlimmste aller Bugs erst kurz nach der Serieneinführung auftaucht und der Bugfix just 201 Bytes benötigen wird -- ganz unabhängig von der Compilerversion, versteht sich.
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.