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 ?
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?
> 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.
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.
> 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.
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. ;-)