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
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.
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.
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)
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
> 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.
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.
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.
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.
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
voidfoo(doublea);
2
3
intmain(){
4
floata=2.2f;
5
foo(a);
6
return0;
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.
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?
> 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.
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
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.
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.