Im Artikel https://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung steht zu -Os dass dies bei AVR die bevorzugte Einstellung sei, allerdings vermisse ich dazu eine Begründung. Ich sehe in meinen Projekten, dass -Os den Flash-Bedarf um 5% bis 10% verringert. Dafür ist die Anzahl von Funktionsaufrufen und der RAM Bedarf höher. Mir geht viel häufiger das RAM aus, als der Flash. Und Stack Überläufe sind besonders eklig. Darum leuchtet mir nicht ein, warum -Os pauschal bevorzugt wird. Kennt jemand den Grund?
:
Verschoben durch Admin
>Darum leuchtet mir nicht ein, warum -Os pauschal bevorzugt wird. Kennt >jemand den Grund? Es gibt keinen. Wähle die Optimierung die dir am besten passt.
Stefan U. schrieb: > Und Stack Überläufe sind besonders eklig. Was besonders bei common subexpression elimination droht. Solange man nicht durch -Os den nächstkleineren Mikropoezossor wählen kann, was die Flashgröße angeht, ist das eh witzlos. Siehe auch Nigel Jones zu dem Thema: http://embeddedgurus.com/stack-overflow/2008/09/efficient-c-tips-4-use-speed-optimization/
Stefan U. schrieb: > Dafür ist die Anzahl von Funktionsaufrufen und der RAM > Bedarf höher. Ein Call kostet 2 Byte RAM, ist also nicht teuer. Wie hast Du festgestellt, daß mehr RAM benötigt wird? Stefan U. schrieb: > Darum leuchtet mir nicht ein, warum -Os pauschal bevorzugt wird. Kennt > jemand den Grund? Atmel war lange Zeit sehr knauserig mit Flash, die AT90S hatten nur 2..8kB Flash. Und die ersten AVR-GCCs optimierten auch nicht besonders. Ich hatte mal versucht, ein Programm vom AT89C2051 auf den AT90S2313 zu portieren. Das Ergebnis war ~4kB groß, also keine Chance.
> Wie hast Du festgestellt, daß mehr RAM benötigt wird?
Das denke ich mir, weil Funktionsaufrufe auch Parameter haben. Und wenn
diese Funktionen wieder Funktionen aufrufen die wiederum Funktionen
aufrufen, steigt der Stack Bedarf deutlich an. Oder etwa nicht?
Hättest du ein Szenario, in denen das in signifikantem Umfang auftritt? Also so, dass es abhängig von -Os vs -O1 einen erheblichen Unterschied macht? Mir fällt da allenfalls die Auflösung von Endrekursion ein, aber die sollte es in beiden geben.
:
Bearbeitet durch User
A. K. schrieb: > Hättest du ein Szenario, in denen das in signifikantem Umfang auftritt? Jones schreibt dazu im verlinkten Artiktel "common sub-expression elimination".
> Hättest du ein Szenario, in denen das in signifikantem Umfang auftritt? Nein, ich habe kein konkretes Szenario. > Ein Call kostet 2 Byte RAM, ist also nicht teuer. Doch, mindestens 2 Bytes pro Call. Beim ATtiny13 (mein am häufigsten verwendeter µC) tut jedes Byte RAM weh. Und bei den größeren Alternativen habe ich so viel Flash, das ich nicht das Gefühl habe, dort jemand -Os zu benötigen.
Nop schrieb: > Jones schreibt dazu im verlinkten Artiktel "common sub-expression > elimination". Tut er. Aber erstens liefert er zwar eine zu Halloween passende Horrorbeschreibung, aber leider kein Beispiel. Und zweitens ist das, was er an dieser Stelle schreibt, blühender Unsinn. Beim in Compilerbau wohlbekannten Begriff "common subexpression elimination" werden mehrfach auftretende Teilrechnungen mit gleichem Ergebnis nur einmal durchgeführt und ggf. zwischengespeichert. Spart sowohl (Code-) Platz als auch Zeit. Mit Unterprogrammen hat das nichts zu tun. Das führt allerdings zu zusätzlichen Variablen, vorzugsweise Registern, für diese Teilergebnisse. Die können dann ggf. etwas mehr Stack verbraten, zur Speicherung oder wg. push/pull der Register. Wer den Stack an der Kante der Kapazität fährt, der kann das mit viel Pech zu spüren kriegen. https://en.wikipedia.org/wiki/Common_subexpression_elimination Was er schreibt kenne ich aber von Microchips Compilern. Speziell die 8-Bit PICs neigen zu identischen Codestückchen an vielen Stellen. Die durch Unterprogramme zu ersetzen kann sich bei Optimierung auf (Code-) Platz lohnen. In Architekturen mit Registern variieren die Register, weshalb das da weniger bringt. Keine Ahnung, wie Microchip das nennt. In verschachtelter Form ist mir das dort aber nicht begegnet, also mit einem Call in einem solchen Codestückchen, der wiederum auf ein solches Codestückchen mit einem Call drin, der wiederum ...
:
Bearbeitet durch User
Stefan U. schrieb: > Beim ATtiny13 (mein am häufigsten > verwendeter µC) tut jedes Byte RAM weh. Leg beim nächsten Einkauf einen Groschen drauf und nimm einen ATtiny25. Oder programmier das Teil einfach in Assembler.
> Leg beim nächsten Einkauf einen Groschen drauf und nimm einen ATtiny25.
Ich komme doch klar, kein Bedarf.
Unter anderem komme ich deswegen klar, weil ich mich mit den
Compiler-Optionen auseinander setze, anstatt einfach einen größeren
Controller zu verwenden.
Da es für mich ein Hobby ist, kann und möchte ich mir den Zeitaufwand
leisten.
Aber interessant ist doch:
Du hast mir den nächst größeren ATtiny25 empfohlen, um RAM Problemen
wegen -Os aus dem Weg zu gehen. Der hat jedoch auch doppelt so viel
Flash, also macht dann -O1 doch viel mehr Sinn - zumindest als
Standardempfehlung. Denn so gehe ich meinem Stack-Engpass aus dem Weg,
und bekomme auch noch bessere Performance obendrauf.
Warum sollte ich einen größeren und teureren Controller nehmen, wenn es mit -Os sowohl beim Flash als auch beim RAM reicht? Selbst wenn es nur 10 ct sind, macht das viel aus bei Stückzahlen in den Millionen. Und wenn ich den Auftrag nur dadurch akquirieren kann, dass ich eben 10 ct preiswerter als die Konkurrenz bin, ist der Gewinn noch größer.
Stefan U. schrieb: > Beim ATtiny13 (mein am häufigsten > verwendeter µC) tut jedes Byte RAM weh. Mir überhaupt nicht. Bei 1kB Flash stoße ich immer nur an die Flashgrenze. Die RAM-Größe hat mir beim ATtiny13 noch nie Probleme bereitet. Wenn man bei der Programmierung sparsam mit globalen Variablen umgeht, ist der RAM kaum der Flashenhals. Ich lege sogar oft konstante Arrays und Strings zugunsten der besseren Lesbarkeit in den RAM und nehme für Flagvariablen ein ganzes Byte. Funktionsaufrufe kosten oft nur 2 Byte, da die Variablen in Registern übergeben werden. Manchmal zwingen sie auch den Compiler, die Variablen in Registern zu halten, d.h. sparen RAM. Ich hab jedenfalls keine merkbaren Unterschiede festgestellt. Deutlich Mehrbelastung des RAM bewirkt aber die abgeschaltete Optimierung -O0. Da ich keine Millionen Stückzahlen programmiere, ist der MC-Preis nur wenig relevant. Ich nehme daher als 8-Pinner bevorzugt den ATtiny85 (8kB Flash) und rechne auch float darauf. Der ATtiny13 steckt nur noch in alten Projekten, als es den ATtiny85 noch nicht gab.
:
Bearbeitet durch User
Also ich sag euch mal was bei mir (winzige Sensoren im industriellen Umfeld, Platinen teilweise kleiner als ein Fingernagel) die häufigsten Gründe sind warum der kleine Controller für eine Anwendung nicht ausreicht und man etwas anderes (gößeres) braucht: 1. Zu wenig Flash für die Anwendung (manchmal sind 1536 Bytes halt doch etwas knapp) 2. Fehlende oder unzureichende Peripherie [lange nichts] 3. Zuwenig RAM (z.B. steht von vornherein (!) fest daß ich für eine ganz bestimmte Anwendung mindestens einen 4k Puffer oder so brauchen werde, zusätzlich zum sonstigen Kleinkram, dann bin ich mit einem Schlag dick drüber während ich sonst immer dick drunter bin, egal was ich mache)
Bernd K. schrieb: > die häufigsten > Gründe sind warum der kleine Controller für eine Anwendung nicht > ausreicht und man etwas anderes (gößeres) braucht: Reden wir schon über M4 oder zunächst noch über M0 ;-)
m.n. schrieb: > Reden wir schon über M4 oder zunächst noch über M0 ;-) M0 wäre schon einer der "großen". Also zum Beispiel ein kleiner Kinetis mit 8k Flash, fast schon überdimensioniert für die meisten Anwendungen. Jedoch wenn ich über Hobbyprojekte nachdenke wäre ein M0+ für mich die Untergrenze, mit nem 8051 und dem schrottigen Keil-Compiler möchte ich mich privat nicht herumschlagen und auch den AVRs weine ich keine Träne nach. Mit nem MKE04 kann man schon vernünftig und angenehm arbeiten und es gibt ne exzellente und aktuelle Toolchain und Debuggingmöglichkeiten dafür, alles was kleiner ist fass ich nur gegen Bezahlung an, nochmal 20 Cent pro Exemplar zu sparen als alleiniger Vorteil wäre im Hobby vollkommen irrelevant.
:
Bearbeitet durch User
Bernd K. schrieb: > mit nem 8051 und dem schrottigen Keil-Compiler möchte ich > mich privat nicht herumschlagen Naja, der Keil C51 war so sau effizient, daß er erst den Weg für C auf MCs bereitet hat. Vorher haben alle nur in Assembler ihre OTP-PICs usw. mühsam programmiert. Ich fand den Keil C51 einfach nur geil. Float war mit ~1kB auch auf nem AT89C2051 einsetzbar. Der 8051 ist ideal für Steuerungen und da ist auch der RAM völlig ausreichend. Für Grafik, Ethernet, Webinterface ist der 8051 aber nie gedacht gewesen.
Peter D. schrieb: > Ich fand den Keil C51 einfach nur geil. Float war mit ~1kB auch auf nem > AT89C2051 einsetzbar. Der 8051 ist ideal für Steuerungen und da ist auch > der RAM völlig 128-256 Bytes RAM ist die optimale Grösse für einen 51er. Für mehr war die Architektur nicht konstruiert.
Peter D. schrieb: > Ich fand den Keil C51 einfach nur geil. Gut war auch, daß man an richtiger Stelle 2 x 0x90 in die C51.EXE schreiben konnte und anschließend das Dongle den LPT1 nicht blockierte ;-)
A. K. schrieb: > Nop schrieb: >> Jones schreibt dazu im verlinkten Artiktel "common sub-expression >> elimination". > > Tut er. Aber erstens liefert er zwar eine zu Halloween passende > Horrorbeschreibung, aber leider kein Beispiel. > > Und zweitens ist das, was er an dieser Stelle schreibt, blühender > Unsinn. Beim in Compilerbau wohlbekannten Begriff "common subexpression > elimination" werden mehrfach auftretende Teilrechnungen mit gleichem > Ergebnis nur einmal durchgeführt und ggf. zwischengespeichert. Ja, das ist mir auch aufgefallen. Die Zusammenfassung gleichartigen Codes zu Unterprogrammen nennt sich "Code Factoring" oder beim Keil C51 "Common Block Subroutines". Der GCC macht kein Code Factoring (und wenn doch, gäbe es ganz sicher eine Option, um es unabhängig von anderen Optimierungen abzuschalten). Es gab zwar vor vielen Jahren einen Anlauf in diese Richtung, die Entwicklung wurde aber bald wieder eingestellt, da kein wirklicher Nutzen erkennbar war.
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.