Forum: Compiler & IDEs C++ Exceptions mit gcc-arm-none-eabi


von Sebastian V. (sebi_s)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe bisher nur mit AVR µCs gearbeitet und schaue mir nun die STM32 
Serie an. Ich habe das STM32F4Discovery Board hier und teste gerade C++ 
Code mit Exceptions. Ich habe ein vorhanderes größeres Projekt, welches 
ursprüchlich für den PC programmiert wurde und Exceptions nutzt, und 
dies soll nun auf µC portiert werden. Mich interessiert daher wie viel 
Overhead Exceptions auf den Cortex-M4 µCs haben. Man hört ja teilweise, 
dass Exceptions kein Laufzeit Overhead haben wenn keine Exception 
geworfen wird. Hat hier schon jemand Erfahrungen mit Exceptions auf ARM 
µCs gemacht?

Ich habe dazu ein kleines Beispielprojekt angefangen, welches ich 
angehängt habe (Es ist eine Makefile dabei, allerdings habe ich das 
ganze unter Windows erstellt, da mich CooCox in den Wahnsinn getrieben 
hat). Prinzipiell funktionieren die Exceptions allerdings nur bis 
Optimierungslevel O1. Bei O2, O3 und Os macht der µC sonstwas, da keine 
LED eingeschaltet wird. Hat hier jemand eine Idee wieso die höheren 
Optimierungslevel nicht funktionieren? Was mich auch stark gewundert hat 
ist, dass die Codegröße sich von 1KB auf 60KB mit Exceptions vergrößert 
hat. Klar Exceptions zu behandeln ist nicht einfach aber so viel Code?

von Sebastian V. (sebi_s)


Lesenswert?

Ich habe gerade noch ein wenig rumprobiert und muss einige meiner 
Aussagen korrigieren. Tatsächlich funktioniert das Optimierungslevel Os 
doch, aber O2 und O3 immer noch nicht. Auch hat das Ganze nichts mit den 
Exceptions zu tun sondern trifft auch auf Code ohne Exceptions zu. 
Weiter habe ich festgestellt, dass der Code nur dann nicht läuft wenn 
ich das -O2 und -O3 Flag beim Linken mit angebe. Man kann jetzt zwar mit 
dem Os Optimierungslevel arbeiten aber trotzdem frage ich mich wieso der 
Linker verrückt spielt wenn man -O2 oder -O3 übergibt.

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


Lesenswert?

Sebastian V. O. schrieb:
> nur dann nicht läuft wenn ich das -O2 und -O3 Flag beim Linken mit
> angebe

Das ist besonders seltsam, denn eigentlich sollte sich der Linker
darum gar nicht kümmern.

Ruf' den Compiler(treiber) mal mit der Option -v auf, dann erzählt
er dir, mit welchen Optionen er die einzelnen Backends startet.

von Oliver (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Das ist besonders seltsam, denn eigentlich sollte sich der Linker
> darum gar nicht kümmern.

Seit LTO tut er das aber.

Oliver

von Sebastian V. (sebi_s)


Angehängte Dateien:

Lesenswert?

LTO hatte ich auch schon im Verdacht aber wenn ich LTO deaktiviere 
funktioniert Os auch nicht mehr, nur noch O0 und O1. Ich habe nun den 
Fehler aber weiter eingrenzen können auf den Code der für meine main.cpp 
(ohne Exceptions) generiert wird. Mit deaktiviertem LTO funktioniert 
alles wenn ich die main.cpp mit O1 compiliere. Alle höheren 
Optimierungslevel funktionieren nicht mehr. Es liegt aber definitiv an 
der main.cpp denn alle anderen .c Dateien kann ich mit O3 oder Os 
compilieren. Ich habe mal die generierten Assemblies von meiner main.cpp 
angehängt. Eventuell kann dort jemand einen Fehler entdeckt. Meine 
Assemblerkenntnisse (erst recht für ARM) sind leider recht beschränkt.

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


Lesenswert?

Sebastian V. O. schrieb:
> Eventuell kann dort jemand einen Fehler entdeckt.

Wenn es erst beim Linken passiert, helfen die dir gar nichts, denn
der Witz an LTO ist ja gerade, dass der Maschinencode zur Linkzeit
nochmal geändert wird.

von Sebastian V. (sebi_s)


Lesenswert?

Der Test gerade war ohne LTO. Ich hoffe daher, dass der Linker mir nicht 
nochmal irgendwas kaputt macht. Falls der oben von mir hochgeladene 
Assemblercode keine groben Auffälligkeiten zeigt kann ich nochmal ein 
Disassembly von dem gelinkten Zeug machen.

von FelixW (Gast)


Lesenswert?

Sebastian V. O. schrieb:
> Was mich auch stark gewundert hat
> ist, dass die Codegröße sich von 1KB auf 60KB mit Exceptions vergrößert
> hat. Klar Exceptions zu behandeln ist nicht einfach aber so viel Code?

In den Exceptions gibt es eine "demangle" funktion, welche den 
funktionsnamen? wiederherstellt, wo die Exception geworfen wurde. Dieser 
frisst viel Code.

Bei NXP mit mitgelieferten C++ wird der glaube ich irgendwie übergangen 
und damit der Code klein.

Gruß Felix

von Sebastian V. (sebi_s)


Angehängte Dateien:

Lesenswert?

Ich habe hier nochmal Disassemblies vom ganzen Programm angehängt. O1 
läuft und O2 nicht. Sind ca. 30 Zeilen unterschiedlich in der main und 
factorial Funktion. Bis auf die main.cpp wurde mit Os compiliert.

von Sebastian V. (sebi_s)


Lesenswert?

Ok ich habe mich jetzt selbst durch den Assembler Code gearbeitet und 
festgestellt, dass Zugriffe auf die Register des µC verändert wurden. 
Das Problem ist in den folgenden Zeilen C-Code:
1
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // Clock für Port D aktivieren
2
    GPIOD->MODER = 0x55000000; // Pin 12..15 als Ausgang deklarieren
Ab Optimierungslevel O2 entscheidet sicher Compiler die Zugriffe 
umzuordnen, sodass zuerst GPIOD->MODER und dann RCC->AHB1ENR geschrieben 
wird. Offensichtlich scheint das Ganze in dieser Reihenfolge nicht zu 
funktionieren und die LEDs bleiben dunkel. Durch eine memory barrier 
konnte ich das Problem lösen, allerdings finde ich dies eine unschöne 
Lösung. Ich kann mir auch kaum vorstellen, dass ich bisher der einzige 
bin der auf dieses Problem gestoßen ist.

von Oliver (Gast)


Lesenswert?

Hm.

Die Register sollten eigentlich volatile sein, und ich war mir bis eben 
eigentlich ziemlich sicher, daß der Compiler volatile statements nicht 
frei umsortieren darf.

Leider finde ich auf die Schelle nichts dazu iMac-Standard ;)

Oliver

von Oliver (Gast)


Lesenswert?

... im C-Standard

Autokorrektur ist murks...

Oliver

von Sebastian V. (sebi_s)


Lesenswert?

OK ich habe nochmal genau in den Assembler Code geguckt. Tatsächlich 
werden die Daten doch in der korrekten Reihenfolge in den Speicher 
zurück geschrieben. Ich habe mich durch die Reihenfolge in der die Daten 
in ein Register geschrieben werden verwirren lassen. Allerdings sind 
beiden Store Befehle direkt nacheinander. Macht einem hier eventuell das 
Pipelining einen Strich durch die Rechnung? Oder das Aktivieren des 
Takts dauern einen kurzen Moment?

von Stephan (Gast)


Lesenswert?

wegen der Code-Größe: RTTI deaktivieren?
aber mach erst mal die andere Sache zu ende.
Bin gespannt obs doch noch klappt.

Stephan

von Sebastian V. (sebi_s)


Lesenswert?

Ich habe das Ganze jetzt noch genauer analysiert und in der hexfile 
rumgepfuscht um NOPs zwischen die beiden Stores einzufügen. Dabei habe 
ich festgestellt, dass es mindstens zwei NOPs braucht damit die LEDs 
funktionieren. Warum habe ich immer noch nicht ganz verstanden.

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.