Hi, ich bekomme es nicht hin, daß der avr-gcc inhaltsgleiche Konstanten so anlegt, daß sie nur einmal Speicher verbaten. Z.Bsp. zwei Strings im PROGMEM Der Schalter -fmerge-constants führt irgendwie nicht zum Erfolg. Wobei der ja bei -Os eigentlich sowieso schon aktiv sein müsste, oder ?
Mann, das hier is kein Chat. Im Forum dauert es ein wenig bis man eine Antwort bekommt. Geduld, junger Padawan...
Konstantin schrieb:
> Z.Bsp. zwei Strings im PROGMEM
Was meinst du mit "Z.Bsp."? Ist es nicht vielleicht genau das, worum es
dir geht? Bei Flash-Strings, die per PSTR angelegt werden, funktioniert
das Zusammenlegen grundsätzlich nicht. Du wirst dann schon den String
einmal irgendwo mit Namen anlegen, und ihn dann mehrfach referenzieren
müssen.
> Bei Flash-Strings, die per PSTR angelegt werden, funktioniert > das Zusammenlegen grundsätzlich nicht Wie kommt das? Gibts einen Grund, warum das nicht geht? Oder ist das einfach im avr-gcc nicht implementiert?
Wenn du den String unbedingt unter zwei verschiedenen Namen ansprechen willst, kannst du auch ein Alias-Symbol verwenden.
> Bei Flash-Strings, die per PSTR angelegt werden, funktioniert > das Zusammenlegen grundsätzlich nicht Schade.. ist doch eigentlich die einfachste aller Optimierungen. Wundert mich, daß der GCC das nicht kann. Wie kommt das ? Irgendeine Konstruktion mit benannten Konstanten kommt für mich hier nicht in Frage, da das Programm damit zu unleserlich würde. Dann verschwende ich lieber Speicher. Noch habe ich so grade eben den Platz dazu. Gibt es einen anderen Weg, wie man den GCC dabei etwas auf die Sprünge helfen kann ? Funktioniert -fmerge-constants generell nicht ? Gibt es eine Doku aus der hervorgeht, was der avr-gcc gegenüber dem gcc NICHT macht ?
Klaus schrieb: > Wie kommt das? Gibts einen Grund, warum das nicht geht? Es liegt an den Implementierungsdetails des PSTR-Makros. Guck ihn dir an, dann bekommst du vielleicht ein Gefühl dafür. ;-) > Oder ist das > einfach im avr-gcc nicht implementiert? Standardmäßig legt GCC gleiche Zeichenkettenkonstanten einer Übersetzungseinheit von sich aus zusammen, sofern man nicht gerade im Kompatibilitätsmodus für prä-C89 (-traditional) arbeitet.
Konstantin schrieb: > Irgendeine Konstruktion mit benannten Konstanten kommt für mich hier > nicht in Frage, da das Programm damit zu unleserlich würde. ? Das wage ich zu bezweifeln. Auf Anhieb kenne ich jetzt keinen einzigen Fall, dei dem benannte Konstanten ein irgendwie geartetes Problem hervorrufen würden. Ich kenne aber zig andere Fälle in denen genau das Nichtverwenden von benannten Konstanten zum Problem führte. Texte inline quer über den ganzen Code zu verstreuen ist zb bei Übersetzungsarbeiten ein sicherer Weg ins Chaos. Auch Programme, die GUI-mässig kein einheitliches Nomenklaturkonzept besitzen (die gleichen Dinge heißen an unterschiedlichen GUI Stellen anderes) sind praktisch immer auf quer verstreute Texte zurückzuführen. Wäre ja auch zu einfach, wenn man alle verwendeten Texte an einer Stelle beisammen hätte und Texte einfach aufeinander abstimmen könnte.
Klar, in professionellen Projekten ist das vielleicht besser. Für (m)ein Hobby-Projekt aber nicht. Außerdem ist es nicht überall über den Code verstreut, sondern alles beisammen. Es geht um ein Menü. Konsequent gedacht, müssten also alle Strings in ein .h wandern, eine andere Datei. Wenn was geändert werden soll, muss man zwischen zwei Dateien hin und her schalten. Oder wilde Scroll-Orgien machen, wenn die Strings oben in der .c Datei definiert sind. Jetzt will man den Text eines Menüpunktes eines Untermenüs ändern.. und muss direkt eine neue Konstante anlegen und zwei Stellen ändern. Aber egal..ist wuscht.. ich verzichte drauf, und gut is. Hab keine Lust mich deswegen hier verteidigen zu müssen.
Konstantin schrieb: > Außerdem ist es nicht überall über den Code verstreut, sondern alles > beisammen. Es geht um ein Menü. > Konsequent gedacht, müssten also alle Strings in ein .h wandern, Das ist damit nicht gesagt :-) > eine > andere Datei. Wenn was geändert werden soll, muss man zwischen zwei > Dateien hin und her schalten. Oder wilde Scroll-Orgien machen, wenn die > Strings oben in der .c Datei definiert sind. > Jetzt will man den Text eines Menüpunktes eines Untermenüs ändern.. und > muss direkt eine neue Konstante anlegen und zwei Stellen ändern. OK. Da geb ich dir recht. Aber da man ja auch die Menüs an einer Stelle nach Möglichkeit zusammenfasst, ist das so schlimm auch wieder nicht.
>Aber da man ja auch die Menüs an einer Stelle nach Möglichkeit >zusammenfasst, ist das so schlimm auch wieder nicht. Sag ich doch.. aber schöner wärs, wenn das automatisch passieren würde, oder ? Für solche Sachen ist diese Optimierung ja schliesslich gedacht, wenn ich mich nicht irre. :-) [Neugier on] Habe hier grade keinen Zugriff auf dieses Makro, woran liegts denn genau ?
>Aber egal..ist wuscht.. ich verzichte drauf, und gut is. Hab keine Lust >mich deswegen hier verteidigen zu müssen. Wer angreift, muß auch verteidigen können :-) Was du willst, ist sorgloses drauflos-programmieren UND optimal kleinen Programmcode. Das geht halt automatisch nicht. Compiler werden zwar immer besser darin, nicht das zu tun, was der Programmierer schreibt, sondern das, was er will, aber shit in/shit out gilt immer noch. Wenn du deinen AVR so Knopf auf Kante ausgelegt hast, daß dich diese wenigen zusätzliche Bytes, über die wir hier reden, über die Flashgröße deines Prozessors bringen, dann musst du halt nachdenken. Entweder über eine bessere Programmstruktur, oder über einen größeren Prozessor. Oliver
>Das geht halt automatisch nicht. Doch "eigentlich" ja schon. Eigentlich kann der Compiler das. Aus irgendeinem Grund den ich grad nicht nachgucken kann (bin grad nicht zuhaus) geht es halt mit diesem Makro nicht wie oben jemand schrieb. >shit in/shit out sehe ich da nicht. Wenns zu knapp wird, muss ich den Kram halt verunleserlichen :-)
>Eigentlich kann der Compiler das.
Der Compiler kann Symptome kurieren, eben u.a. durch zuammenfassen von
Stringkonstanten.
Die Ursache, nicht-optimales Programmdesign (=shit auf einer anderen
Ebene), kann er nicht beseitigen.
Aber sei es drum, das ist dein Programm.
Wenn dich diese avr-gcc-Einschränkung (bzw. die avrlibc-Einschränkung)
ernsthaft stört, und du willst und kannst, mach einen Vorschlag für das
PSTR-Makro, mit dem der Compiler das auch optimieren kann. Ist ja alles
open source, da darf man das.
Oliver
Sagmal, wo liest du eigentlich einen Angriff ?
>Die Ursache, nicht-optimales Programmdesign (=shit auf einer anderen
Ebene), kann er nicht beseitigen.
In so einem Fall (theoretisch) schon. Es geht nicht um Algorithmen,
sondern nur um einfache Strings.
Warum das praktisch nicht geht, ist bisher nicht gesagt worden. Aber
wenns nicht geht, gehts halt nicht.
Warum ich das so und nicht anders mache habe ich oben schon begründet.
Für mich ist genau dieses "Design" optimal.
> In so einem Fall (theoretisch) schon. Es geht nicht um Algorithmen, > sondern nur um einfache Strings. > Warum das praktisch nicht geht, ist bisher nicht gesagt worden. Aber > wenns nicht geht, gehts halt nicht. Jörg hat dir doch schon einen Tipp gegeben. >> Wie kommt das? Gibts einen Grund, warum das nicht geht? > Es liegt an den Implementierungsdetails des PSTR-Makros. Guck ihn > dir an, dann bekommst du vielleicht ein Gefühl dafür. ;-) > Für mich ist genau dieses "Design" optimal. \*hust\* ;-) Nur so nebenbei, findest du Beiträge wie diesen Beitrag "Re: GCC: --fmerge-constants ?" schön? Wenn nein, dann lass bitte das Plenken sein.
So, um die Disskusion mal wieder auf Thema zu lenken: So is das Macro PSTR definiert:
1 | # define PSTR(s) (__extension__({static char __c[] PROGMEM = (s); &__c[0];}))
|
Aus meiner naiven Sicht, müsste es für den Compiler möglich sein, zu erkennen, da sind Konstanten mit identischem Inhalt und denen die selbe Adresse zuweisen. Aus dem Macro erkenne ich jetzt noch nicht, was verhindert, dass das funktioniert.
Du meinst, wenn du schreibst: static const int i1 = 1; static const int i2 = 1; dann darf der Compiler daraus eine einzige Variable machen, auf dass &i1==&i2 ? Nope, das darf er m.W. nicht. Und genau da liegt der Hase im Pfeffer.
Es wird eine statische lokale Variable angelegt und ein Pointer darauf "zurückgegeben". Außerhalb der geschweiften Klammern existiert diese Variable gar nicht. Der Compiler kann nicht zusammenlegen, was es gar nicht gibt. ;-)
Stefan Ernst schrieb:
> Der Compiler kann nicht zusammenlegen, was es gar nicht gibt. ;-)
Es gibt sie schon, weil "static", aber sie sind nicht sichtbar. Ist für
den Compiler schon ein Unterschied.
Ok, jetzt habe ich verstanden warum es nicht klappt. Die Strings müssten also global gelten, was aber nicht geht. Richtig ?
> Du meinst, wenn du schreibst: > static const int i1 = 1; > static const int i2 = 1; > dann darf der Compiler daraus eine einzige Variable machen, auf dass > &i1==&i2 ? ok, das &i1 != &i2 gelten muss, leuchtet ein. Wenn ich aber schreibe char *i = "Text"; char *j = "Text"; dann würde der Compiler den String nur einmal im Flash ablegen und ihn 2 mal ins RAM kopieren, richtig?
A. K. schrieb: > Es gibt sie schon, weil "static", aber sie sind nicht sichtbar. Ist für > den Compiler schon ein Unterschied. Der Compiler könnte sie schon zusammenlegen, aber er macht das gerade mal nicht. Das ist ein Bug, aber er hat eben eine relativ geringe Priorität, da außer der avr-libc sonst praktisch niemand dadurch genervt ist: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21018 Ist ein typisches Beispiel der fehlenden man power, die ich hier Beitrag "Re: "Optimierung" bei Multiplikation" bereits angesprochen habe. Es nützt halt wenig, als anonymer Gast in einem Forum große Bögen über einen "Fork" zu spucken, wenn es nicht einmal genügend Leute gibt, die sich der weniger priorisierten Bugs annehmen können. Dieser Bug hat nun weiß Gott auch nichts mit irgendeiner "Versionitis" des GCC zu tun, der ist seit Urzeiten da drin.
Klaus schrieb: > Wenn ich aber schreibe > > char *i = "Text"; > char *j = "Text"; > > dann würde der Compiler den String nur einmal im Flash ablegen und ihn 2 > mal ins RAM kopieren, richtig? Nein, es genügt, wenn er ihn einmal ins RAM kopiert. Die Zeiger i und j zeigen auf das gleiche Objekt; das ist vom C-Standard explizit zugelassen.
Na toll, jetzt war ich gerade überzeugt, dass der Compiler die gar nicht zusammen legen darf, und dann sowas... ;)
Ok, dann hat sich dieses Diskussion ja erledigt. >"This behaviour is reproducable as well on the i386 target, so it looks like >not really related to the avr backend." Dann ist ja AVR-Team ja auch garnicht dafür zuständig.
Jörg Wunsch schrieb: > Klaus schrieb: > >> Wenn ich aber schreibe >> >> char *i = "Text"; >> char *j = "Text"; >> >> dann würde der Compiler den String nur einmal im Flash ablegen und ihn 2 >> mal ins RAM kopieren, richtig? > > Nein, es genügt, wenn er ihn einmal ins RAM kopiert. Die Zeiger i > und j zeigen auf das gleiche Objekt; das ist vom C-Standard explizit > zugelassen. Aber auch nur deshalb, weil "Text" auch in C als Stringliteral den Ausnahmestatus hat und als "Konstante" in dem Sinne gilt, wie sie dann erst in C++ implementiert wurden. C Konstante != C++ Konstante Erst in C++ sind Konstanten allgemein so definiert worden, wie man sich das landläufig so vorstellt :-) So gesehn hat Klaus mit seinem Beispiel in C++ zwar unrecht, in C hat er aber recht :-)
Konstantin schrieb: >>"This behaviour is reproducable as well on the i386 target, so it looks like >>not really related to the avr backend." > > Dann ist ja AVR-Team ja auch garnicht dafür zuständig. So kann man das auch abtun, wenn man will, dass sich nie etwas ändert. Das ist doch hier keine Behörde, bei der man am besten arbeitet, wenn man die Zuständigkeit auf andere abschiebt... das ist ein Opensource-Projekt, das einzig und allein davon lebt, dass es jemanden gibt, der motiviert genug ist, etwas zu tun. Da die ganze Sache außer den Microcontroller-Anwendern kein Schwein stört, kannst du noch weitere viele Jahre drauf warten, bis vielleicht einer aus der i386-Ecke ankommt und gerade diesen Bug repariert. Die Jungs da haben genügend anderes zu tun, was ihnen wiederum mehr am Herzen liegt. Die Implementierung von binären Konstanten mit dem Präfix 0b war auch keinesfalls eine reine AVR-Angelegenheit, trotzdem habe ich eine seinerzeitige Diskussion hier (die eigentlich mehr dem Nachweis dienen sollte, dass das relativ einfach implementierbar ist) zum Anlass genommen, diese Änderung bis zum bitteren Ende durchzupeitschen.
>Präfix 0b
Iss ja gut jetzt. Durch deine ständige Wiederholung daß du das so toll
gemacht hast ist es irgendwie garnicht mehr toll.
Aber das sei dir überlassen :-)
Abgesehen davon ist deine Arbeit an der avr-libc wirklich toll (dies als
wiedergutmachung erwähnt :-)
Gast schrieb: >>Präfix 0b > > Iss ja gut jetzt. Durch deine ständige Wiederholung daß du das so toll > gemacht hast ist es irgendwie garnicht mehr toll. OK, OK. Ich wünsche mir einfach nur, dass ein paar Leute mehr sich entsprechend engagieren, statt immer nur zu meckern. Man muss nicht für alles unbedingt die komplette GCC-RTL-Sprache und ihre Zusammen- hänge verstanden haben. Ich werde das Beispiel in Zukunft nicht mehr bringen. ;-)
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.