Forum: Compiler & IDEs GCC: --fmerge-constants ?


von Konstantin (Gast)


Lesenswert?

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 ?

von Konstantin (Gast)


Lesenswert?

Niemand ?

von Klaus (Gast)


Lesenswert?

Mann, das hier is kein Chat. Im Forum dauert es ein wenig bis man eine 
Antwort bekommt.

Geduld, junger Padawan...

von Stefan E. (sternst)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

> 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?

von Rolf Magnus (Gast)


Lesenswert?

Wenn du den String unbedingt unter zwei verschiedenen Namen ansprechen 
willst, kannst du auch ein Alias-Symbol verwenden.

von Konstantin (Gast)


Lesenswert?

> 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 ?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Konstantin (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Konstantin (Gast)


Lesenswert?

>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 
?

von Oliver (Gast)


Lesenswert?

>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

von Konstantin (Gast)


Lesenswert?

>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 :-)

von Oliver (Gast)


Lesenswert?

>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

von Konstantin (Gast)


Lesenswert?

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.

von ......... (Gast)


Lesenswert?

> 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.

von Konstantin (Gast)


Lesenswert?

Jawohl, euer Ehren.
Alberner gehts ja nicht.

von Klaus (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Stefan E. (sternst)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Konstantin (Gast)


Lesenswert?

Ok,

jetzt habe ich verstanden warum es nicht klappt.

Die Strings müssten also global gelten, was aber nicht geht.
Richtig ?

von Klaus (Gast)


Lesenswert?

> 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?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

Na toll, jetzt war ich gerade überzeugt, dass der Compiler die gar nicht 
zusammen legen darf, und dann sowas... ;)

von Konstantin (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von Konstantin (Gast)


Lesenswert?

@Jörg: Du bist schon ein toller Hecht.
Ehre, wem Ehre gebürt.

von Klaus (Gast)


Lesenswert?

Jap, danke für die klärenden Worte :)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Gast (Gast)


Lesenswert?

>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 :-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.