Forum: Compiler & IDEs OHNE(!) Optimierung gehts nichts mehr


von Daniel G. (motello)


Lesenswert?

Hallo zusammen,

entgegen der üblichen Optimierungsprobleme ist es bei mit genau 
umgekehrt: Bei höchster (-Os) Optimierung tritt selten fehlerhaftes 
Verhalten auf. Bei geringerer wird zwar noch die main aufgerufen, aber 
ohne (-O0) Optimierung wird nicht einmal die erste Zeile in main() 
ausgeführt.

Ich hatte die Bootstrap Routine AT91boot... in verdacht, doch sie hat 
allen Tests standgehalten und funktioniert.

Was kann das sein?

ARM9, codesourcery arm-none-eabi-toolchain

Viele Grüße
Daniel Gering

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

- RAM/Stack läuft über
- Programm passt nicht in Flash
- Timing stimmt nicht mehr (ISRs, etc)

Johann

von Sven P. (Gast)


Lesenswert?

Es gibt C-Konstruktionen im GCC, die ohne Optimierung einfach nicht 
laufen. Beispielsweise inb() und outb() und Konsorten unter Linux.

von Simon K. (simon) Benutzerseite


Lesenswert?

volatile vergessen.

von Daniel G. (motello)


Lesenswert?

Hallo,

nein, alles das kann ich ausschließen. Ich suche schon viele Wochen nach 
diesem Fehler und hatte hier schon mal gepostet. Habe schon so viel 
getestet und probiert...

Stackpointer sind in allen Modi initialisiert, Programm nicht 
zeitkritisch, passt definitiv in Flash, von RAM groß genug, inb() und 
outb() nutze ich nicht und es läuft kein OS (bare metal) und die 
vergessenen volatiles sind längst drinnen.

Sogar verschiedene Toolchains habe ich versucht. Aber vor allem: warum 
wird nicht mal die erste main() Zeile ausgeführt?

Ich hoffe Ihr habt noch Ideen, ich verzweifele (schon seit langem)!

Viele Grüße
Daniel Gering

von Sven P. (Gast)


Lesenswert?

Ich sagte, dass inb() und outb() nur Beispiele sind. Genaugenommen 
funktionieren sämtliche Aufrufe von alleinstehenden Inline-Funktionen 
ohne Optimierung nicht.

von Max (Gast)


Lesenswert?

Bin ein bissl unwissend:
>Genaugenommen
funktionieren sämtliche Aufrufe von alleinstehenden Inline-Funktionen
ohne Optimierung nicht.<

Was hrißt das?

von Daniel G. (motello)


Lesenswert?

Sven P. schrieb:
> Ich sagte, dass inb() und outb() nur Beispiele sind. Genaugenommen
> funktionieren sämtliche Aufrufe von alleinstehenden Inline-Funktionen
> ohne Optimierung nicht.

Also unter Inline Funktionen verstehe ich Codeteile die durch den 
Compiler oder preprozessor eingesetzt werden anstatt zu einer Funktion 
zu springen.

inb() und outb() sind doch von Linux bereitgestellte funktionen die ich 
nicht habe weil kein linux läuft (überhaupt kein BS). Oder sehe ich da 
was falsch?

Grüße
DG

von Max (Gast)


Lesenswert?

Nein ich meine mehr im zusammenhang

alleinstehend
optimierung

ansonsten inline ich auch wie ein weltmeister.

von Sven P. (Gast)


Lesenswert?

Daniel G. schrieb:
> Sven P. schrieb:
>> Ich sagte, dass inb() und outb() nur Beispiele sind. Genaugenommen
>> funktionieren sämtliche Aufrufe von alleinstehenden Inline-Funktionen
>> ohne Optimierung nicht.
>
> Also unter Inline Funktionen verstehe ich Codeteile die durch den
> Compiler oder preprozessor eingesetzt werden anstatt zu einer Funktion
> zu springen.
Richtig. Das impliziert dann logischerweise, dass der Funktionsrumpf 
auch im Header definiert sein muss, denn sonst sieht der Compiler ja 
nicht, was er denn direkt einbauen soll.

> inb() und outb() sind doch von Linux bereitgestellte funktionen die ich
> nicht habe weil kein linux läuft (überhaupt kein BS). Oder sehe ich da
> was falsch?
Jein, inb() und outb() sind Inline-Funktionen, die halt nur in den 
Headern liegen und nicht in irgendeiner Bibliothek landen, die 
dazugelinkt wird. Wär ja auch Käse, inb() und Konsorten sind unterm 
Strich nur 'Makros', da wird bestenfalls ein einzelner Assembler-Befehl 
verpackt.

Wenn du nun ohne Optimierung übersetzt, führt der Compiler auch keine 
Inlines aus, sondern setzt dort Verweise in die Wildnis ein (wie bei 
jedem anderen Funktionsaufruf auch) und reicht das an den Linker weiter, 
damit der die Verweise auf die richtigen Funktionen und Bibliotheken 
verbiegt.

Blöderweise liegen so Dinger wie etwa inb() eben nirgendwo, d.h. die 
Verweise landen im Sand.
Wenn man allerdings die Optimierung wieder einschaltet, baut der 
Compiler die Funktionen direkt ein und das Problem mit der Linkerei 
stellt sich erst garnicht.


Warum möchtest du überhaupt die Optimierung abstellen?

von Rolf Magnus (Gast)


Lesenswert?

> Blöderweise liegen so Dinger wie etwa inb() eben nirgendwo, d.h. die
> Verweise landen im Sand.

Wie kommst du darauf? Entweder sind sie als Makros definiert, dann löst 
sie der Präprozessor nach wie vor auf, oder es sind Funktionen, dann 
werden sie halt nicht mehr inline ausgeführt, sondern als 
Funktionsaufruf. Selbstverständlich muß der Compiler auch ohne 
Optimierung korrekten Code produzieren. Aufrufen aber dann einfach 
weglassen darf er die Funktion nicht.

von Peter (Gast)


Lesenswert?

Ich kann mir auch nict vorstellen, das Inline oder Makro nicht gehen 
soll wenn man keine Optimierung eingeschaltet hat. Normalerweise debuggt 
man ja code ohne Optimierung und dabei ist mir noch die etwas 
untergekommen was ohne optimierung nicht geht.

Da die Header datei ja eh durch das include in der gleichen Datei wie 
auch der C code steht, ist es egal ob die Funktion in der header oder in 
der C datei steht, für den Linker ändert das nichts.

von Sven P. (Gast)


Lesenswert?

Linux-Manualseite zu inb():

> You compile with -O or -O2 or similar. The functions are defined as
> inline macros, and will not be substituted in without optimization
> enabled, causing unresolved references at link time.

Anders kann ich mir das nich erklären, heißt natürlich nicht, dass ich 
auch danebenliegen kann.

von Rolf Magnus (Gast)


Lesenswert?

Hmm, steht da tatsächlich. Dann würde mich aber mal wirklich 
interessieren, wie man das hinbekommt. Eigentlich geht sowas gar nicht.

von Bernhard R. (barnyhh)


Lesenswert?

Ganz am Anfang - als eine der ersten Aktionen nach Einschalten oder 
RESET - wird der Stackpointer initialisiert. Wenn jetzt der Prolog (vor 
main) zu früh (vor Initialisierung des Stackpointers) Funktionsaufrufe 
durchführt, dann kann folgendes geschehen:
- Ohne Optimierung werden Calls auf diese Funktionen durchgeführt, die 
spätestens beim Return ins Nirwana abgleiten
- Mit Optimierung geschieht Code-Inlining, also kein Call, kein Nirwana

Das paßt zu den Symptomen.

Bernhard

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Das Problem kann ausgelöst werden durch anderes Timing, zB bei 
aktiviertem Watchdog, oder wenn Teile des Startup-Codes in der 
Applikation in C geschrieben sind. Dazu gehören Konstruktoren in C++, 
Funktionen mit __attribute__((constructor)) (GNU-C) und Code in 
speziellen init-Sections, der nicht in Assembler geschrieben ist.

Johann

von Daniel G. (motello)


Lesenswert?

Bernhard R. schrieb:
> Ganz am Anfang - als eine der ersten Aktionen nach Einschalten oder
> RESET - wird der Stackpointer initialisiert. Wenn jetzt der Prolog (vor
> main) zu früh (vor Initialisierung des Stackpointers) Funktionsaufrufe
> durchführt, dann kann folgendes geschehen:
> - Ohne Optimierung werden Calls auf diese Funktionen durchgeführt, die
> spätestens beim Return ins Nirwana abgleiten
> - Mit Optimierung geschieht Code-Inlining, also kein Call, kein Nirwana
>
> Das paßt zu den Symptomen.
>
> Bernhard

C-Code wird erst aufgerufen wenn alle Stackpointer initialisiert sind.

Für den Startup-Code in Assembler ist es egal welche Optimierungsstufe 
gewählt ist. Nur für C-Code muss mindestens -O1 eingeschaltet sein.

Und wie gesagt, ohne Optimierung wird nicht mal die erste Zeile des 
C-Programms ausgeführt.

Watchdog ist aus, C++ nutze ich nicht, __attribute__((constructor)) auch 
nicht.

Ich habe nicht eine Funktion die als inline gekennzeichnet ist. Und auch 
nur eine Library Funtion nutze ich: memcpy()

Was kann das nur sein???

von Cpt (Gast)


Lesenswert?

Hallo zusammen!

Ich hatte letztens ein ähnliches Problem mit dem AVR32. Bei mir war es 
das Flash und genauer gesagt das Flash Timing. Ich hatte übersehen, daß 
wenn man den Prozessor mit 60 MHz betreiben will, der Flash Controller 
ein Waitstate beim Zugriff braucht ... Das Verhalten war in etwa gleich. 
Längerer Code wurde nur mit höchster Optimierung ordentlich ausgeführt. 
Nur mal als Denkanstoß in eine andere Richtung. Hat mich viel Zeit 
gekostet das Problem zu finden.

Viele Grüße!

Cpt

von Daniel G. (motello)


Lesenswert?

Vielen Dank!

Ich habe mein Problem nach laaaaaaaanger Zeit ebenfalls heute lösen 
können. Hier nachzulesen:

Beitrag "Merkwürdiges Verhalten bei Variablen und for-schleifen"

Stackpointer war nicht aligned.

Viele Grüße
Daniel Gering

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.