Forum: Compiler & IDEs GCC Compiler Flags


von Andreas T. (skycurve)


Lesenswert?

Hallo zusammen,

bei meinen STM32F4 Projekten verwende ich folgende CFLAGS:
1
CFLAGS = -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wall -ffunction-sections -g -O3 -ffast-math -fshort-double -lm -c -DSTM32F405RG -DSTM32F4XX -DUSE_STDPERIPH_DRIVER -D__ASSEMBLY__ -D__FPU_USED

Ich verwende seit geraumer Zeit den
gcc-arm-none-eabi-4_8-2014q2
Compiler.
Nun möchte ich gerne auf die Version
gcc-arm-none-eabi-8-2018-q4
umsteigen.

Problem ist, dass GCC schon seit längerer Zeit die
1
-fshort-double
Anweisung rausgeschmissen hat. Ohne dieser Anweisung wird mit dem neuen 
Compiler ein lauffähiges Binary erzeugt. Allerdings ist dadurch die 
Ausführunszeit auf ~3.5 fache gestiegen.

Es scheint auch keine alternative Anweisung zu geben.
Hat jemand einen Tipp für mich?

Viele Grüße
Andreas

von mh (Gast)


Lesenswert?

Wieso nicht float anstelle von double benutzen? Da vorher eh double == 
float war, kann man einfach alle double im Quelltext mit float ersetzen. 
Sollte eine 5 Minuten Aufgabe sein, das umzusetzen und auf Korrektheit 
zu prüfen.

von STM Apprentice (Gast)


Lesenswert?

mh schrieb:
> Da vorher eh double ==
> float war, kann man einfach alle double im Quelltext mit float ersetzen.

Bei den AVRs ja, aber beim STM32?

Ich weiss es nicht aber ich bezweifle es.

von Carl D. (jcw2)


Lesenswert?

mh schrieb:
> Wieso nicht float anstelle von double benutzen? Da vorher eh double ==
> float war, kann man einfach alle double im Quelltext mit float ersetzen.
> Sollte eine 5 Minuten Aufgabe sein, das umzusetzen und auf Korrektheit
> zu prüfen.

Weil die nach C-Standard trotzdem in double gerechnet werden und man 
auch einen neuen Satz Standardfunktionen bräuchte.
Das Flag stellt(e) die Standardkonformität bzgl. double-Formet um.
(Beim AVR hat man den Zustand immer, ohne ihn abschalten zu können)

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Carl D. schrieb:
> Weil die nach C-Standard trotzdem in double gerechnet werden
Nein, nicht zwingend

Andreas T. schrieb:
> Hat jemand einen Tipp für mich?

- float verwenden
- bei dem uralten Compiler bleiben

Oliver

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andreas T. schrieb:
> Problem ist, dass GCC schon seit längerer Zeit die
>
1
> -fshort-double
> Anweisung rausgeschmissen hat.

Das ist eine maschinenunabhängige Option, und sie hatte schon seit 
langem keinen Effekt mehr auf den maschinenunabhängigen Teil des 
Compilers, ergo ist sie rausgeflogen.

Falls ein Backend dies unterschzützen will, kann es das machen, indem 
das Backend DOUBLE_TYPE_SIZE abhängig von einer (maschinenabhängigen) 
Kommandozeilenoption wie -mshort-double definiert und die Option zu den 
Multilib-Optionen hinzunimmt, so dass Multilib-Varianten passend zu 
-mshort-double verfügnar sind.  Dazu müssen die Libs (libc, libm, 
Header) dies natürlich unterstützen, z.B. dadurch dass die 
Implementierung __SIZEOF_DOUBLE__ berücksichtigt.

-mshort-double o.ä. bzw. Anpassung von DOUBLE_TYPE_SIZE im ARM-Backend 
scheint aber nicht zu geben. Ergo 5 Möglichkeiten:

1) Die alte Version verwenden

2) Die neuen Tools verwenden und damit leben.

3) float nehmen.

4) Schauen, ob es einen kommerziellen Port gibt mit der Anforderung.

5) Selbst Hand anlegen.

: Bearbeitet durch User
von mh (Gast)


Lesenswert?

Carl D. schrieb:
> Weil die nach C-Standard trotzdem in double gerechnet werden und man
> auch einen neuen Satz Standardfunktionen bräuchte.

Ok die Standardfunktionen sind bei C tatsächlich ein kleines aber 
lösbares Problem. Es gibt alle(?) Funktionen auch für float, man muss 
nur nen f an den Namen hängen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

mh schrieb:
> Wieso nicht float anstelle von double benutzen?

Weil das nicht unbedingt das Problem mit der Codegröße behebt:  Wenn 
z.B. printf verwendet wird, unterstützt es immer auch 64-Bit double, und 
gerade wenn float per Hardware unterstützt wird, double aber nicht, 
ergibt -fshort-double merklich kleineren Code weil die Libs anders 
generiert werden.

von Andreas T. (skycurve)


Lesenswert?

Ich verwende im Code an keiner einzigen Stelle 'double', nur float (und 
andere festkomma-Datentypen). Mir ist nicht klar, warum dieser Befehl 
dann mit dem alten Compiler eine Auswirkung hat und warum die 
Ausführungszeit mit dem neuen Compiler so stark angestiegen ist.

von mh (Gast)


Lesenswert?

Für den Wechsel von double nach float ist evtl. die Option 
-Wdouble-promotion hilfreich. Beim gcc scheint die Option allerdings 
unvollständig.

Das Beispiel
1
void foo(double a);
2
3
int main() {
4
    float a = 2.2f;
5
    foo(a);
6
    return 0;
7
}
liefert bei clang ne Warnung, beim gcc nicht.

Johann L. schrieb:
> mh schrieb:
>> Wieso nicht float anstelle von double benutzen?
>
> Weil das nicht unbedingt das Problem mit der Codegröße behebt:  Wenn
> z.B. printf verwendet wird, unterstützt es immer auch 64-Bit double, und
> gerade wenn float per Hardware unterstützt wird, double aber nicht,
> ergibt -fshort-double merklich kleineren Code weil die Libs anders
> generiert werden.

Im Ausgangspost wird explizit nur von Ausführungszeit gesprochen. Ich 
behaupte jetzt mal ohne Grundlage, dass in diesem Fall nicht printf das 
Problem wäre.

von mh (Gast)


Lesenswert?

Andreas T. schrieb:
> Ich verwende im Code an keiner einzigen Stelle 'double', nur float (und
> andere festkomma-Datentypen). Mir ist nicht klar, warum dieser Befehl
> dann mit dem alten Compiler eine Auswirkung hat und warum die
> Ausführungszeit mit dem neuen Compiler so stark angestiegen ist.

Wie bist du dann dazu gekommen der einen Option die "Schuld" zu geben, 
nachdem du ~5 Jahre Compilerentwicklung übersprungen hast?

von Gerd E. (robberknight)


Lesenswert?

Andreas T. schrieb:
> Problem ist, dass GCC schon seit längerer Zeit die
>
1
> -fshort-double
2
>
> Anweisung rausgeschmissen hat. Ohne dieser Anweisung wird mit dem neuen
> Compiler ein lauffähiges Binary erzeugt. Allerdings ist dadurch die
> Ausführunszeit auf ~3.5 fache gestiegen.

Was passiert denn, wenn Du diese Option beim alten Compiler weglässt? 
Ist die Ausführungszeit dann ähnlich wie beim neuen deutlich langsamer 
oder verhält das sich dort anders?

Andreas T. schrieb:
> Ich verwende im Code an keiner einzigen Stelle 'double', nur float (und
> andere festkomma-Datentypen). Mir ist nicht klar, warum dieser Befehl
> dann mit dem alten Compiler eine Auswirkung hat und warum die
> Ausführungszeit mit dem neuen Compiler so stark angestiegen ist.

Schau mal anhand des Map-Files vom Linker was da für Funktionen 
dazukommen. Ist natürlich vor allem aussagekräftig, wenn das Problem 
schon mit dem alten Compiler ähnlich auftritt und Du damit direkt die 
Map-Files mit/ohne -fshort-double vom selben Compiler vergleichen 
kannst.

Vermutlich bekommst Du schon durch die Liste der hinzukommenden 
Funktionen eine gute Idee wo das Problem steckt.

von Andreas T. (skycurve)


Lesenswert?

Ich habe die Laufzeiten mit dem alten Compiler mit und ohne dieses Flags 
verglichen. Auch beim alten Compiler hat dieses eine ca ~3.5 fache 
Performance gebracht.

Habe nun ein Flag gefunden, das mit dem neuen Compiler die selbe 
schnelle Laufzeit bringt
1
-fsingle-precision-constant

Der Rest der CFLAGS bleibt gleich.

Vielen Dank für eure Tipps.

Viele Grüße
Andreas

von Gerd E. (robberknight)


Lesenswert?

Ich vermute Du hast weiterhin irgendwo in Deinem Code ein Problem und 
empfehle es zu finden und richtig zu lösen.

Diese Compiler-Optionen, egal ob die alte oder neue, verstecken es nur, 
lösen es aber nicht richtig.

von mh (Gast)


Lesenswert?

Andreas T. schrieb:
> Habe nun ein Flag gefunden, das mit dem neuen Compiler die selbe
> schnelle Laufzeit bringt-fsingle-precision-constant

Du hast also nicht nur floats in deinem Quelltext. Irgendwo sind double 
Konstanten. Es gibt kein double Gegenstück für integer promotion, aber 
float * double ist immer noch double.

von jaksdhkjhec (Gast)


Lesenswert?

>Ausführunszeit auf ~3.5 fache gestiegen.
Sowas hatte ich auch. Ich habe an alle Konstanten dann ein "f" hängen 
müssen. Dann flutsche es wieder.

also
1
x = 1.0f;
anstatt
1
x =  1.0;

von mh (Gast)


Lesenswert?

jaksdhkjhec schrieb:
> also
> x = 1.0f;
> anstatt
> x =  1.0;

Wenn x nen float ist, sollte es in diesem Beispiel keinen Unterschied 
machen.

von wizardmonkey (Gast)


Lesenswert?

Relatiert:
https://www.quora.com/What-is-the-difference-between-float-and-double-in-C-language-How-is-it-stored-in-the-memory

Float ist ein doubleword jeh nach System,
Double ist ein quadword.

Worin der unterschied zwischen int32_t und int32_t besteht sollte man 
nicht erklären müssen

von wizardmonkey (Gast)


Lesenswert?

*es muss natürlich int64_t lauten

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.