Forum: Compiler & IDEs Compilter Optimierungen für bestimmte Codeabschnitte deaktivieren


von Nerb (Gast)


Lesenswert?

Hallo,

ich habe das Problem, dass alle Compileroptimierungen ( O1 bis O3 und 
Os) mein Programm nicht mehr richtig funktionieren lassen, sonst aber 
der Code nicht mehr in den Speicher passt....

Jetzt meine Frage: Kann man die Optimierungen für bestimmte Codeblöcke, 
von denen ich weiß dass sie durch die Optimierungen kaputt gemacht 
werden, per Precompiler Befehl oder durch etwas anderes ausschalten?

Grüße,
Philip

von (prx) A. K. (prx)


Lesenswert?


von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Nerb schrieb:
> Jetzt meine Frage: Kann man die Optimierungen für bestimmte Codeblöcke,
> von denen ich weiß dass sie durch die Optimierungen kaputt gemacht
> werden, per Precompiler Befehl oder durch etwas anderes ausschalten?

Wenn der Optimierer Dein Programm derart ändert, dass Dein Programm 
nicht mehr wunschgemäß funktioniert, kannst Du in über 90% der Fälle 
davon ausgehen, dass der Fehler im Programm ist und nicht im Optimierer 
des Compilers.

Zeig doch mal Deine "bestimmten Codeblöcke".

von Marco M. (marco_m)


Lesenswert?

Ich nehme mal an, daß du von GCC sprichst. GCC hat ab Version 4.4 
Pragmas mit denen man funktionsgenau die Optimierung steuern kann, man 
kann die Optimierungsoptionen auch als Funktionsattribute anhängen:

http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html

Wenn dein Programm allerdings bei Einsatz des Optimierers nicht mehr 
funktioniert, dann ist in 99.9% der Fälle nicht der Optimierer schuld, 
sondern der Programmierer, der sich einen Nachmittag lang mal hinsetzen 
sollte um das hier zu lesen:

http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

von Opti (Gast)


Lesenswert?

Oder arbeite mit Libs. Damit kannst Du jede Lib anders optimieren und es 
spart Zeit beim Compilern des Hauptprogramms.

von Oliver S. (oliverso)


Lesenswert?

Der beste Weg ist immer noch, zunächst mal fehlerfreien Programmcode zu 
schreiben. Code, der durch die Optimierung "kaputt gemacht" wird, ist 
nun mal nicht fehlerfrei.

Oliver

von Nerb (Gast)


Lesenswert?

Hallo,

danke für die vielen Antworten. Die Links habe ich mir durchgelesen, da 
steht vieles Nützliche drin. Bevor ich aber für unterschiedliche 
Funktionen den Optimierungsgrad ändere, suche ich doch lieber nach der 
Ursache im Code, damit ich später alles einheitlich habe. Gefunden habe 
ich folgendes:

Mein Programm:

global.h
1
extern uint8_t globaleVariable;

global.c
1
uint8_t globaleVariable = 0;

transceive.c
1
#include "global.h"
2
if(globaleVariable == 1)
3
{
4
    Dieser Code wird nicht aufgefuehrt, wenn ich optimiere.
5
}

So, nehme ich aber jetzt aber das "extern" in global.h weg, dann geht 
mein Programm. Da aber von verschiedenen anderen .c Dateien auf die 
Variable zugegriffen wird, brauche ich das extern aber. Wisst ihr, wo da 
der Wurm drin steckt?

Grüße,
Philip

von Εrnst B. (ernst)


Lesenswert?

Nerb schrieb:
> Wisst ihr, wo da
> der Wurm drin steckt?

In dem Teil, den du nicht zeigst. Such mal in allen Source-Files nach 
"globaleVariable", vermutlich ist die irgendwo ein zweites mal 
deklariert.

von Nerb (Gast)


Lesenswert?

Hi,

sie ist nirgends zweimal deklariert, sondern nur einmal in global.c. 
Wenn die variable in transceive.c abgefragt wird, hat sie noch keinen 
Wert zugewiesen bekommen (ist 0, aber nicht wegen der Zuweisung in 
global.c, sondern weil Avr Studio 6 und gcc Variablen automatisch 0 
setzen). Hat jemand noch eine Idee? Ich finde den Fehler nicht, finde es 
aber komisch, dass es ohne das extern geht.


Grüße,
Philip

von Klaus (Gast)


Lesenswert?

Ich setzte all mein Geld auf volatile

von Rolf Magnus (Gast)


Lesenswert?

Klaus schrieb:
> Ich setzte all mein Geld auf volatile

Mit anderen Worten: Könnte es vielleicht sein, daß auf globaleVariable 
auch aus einer ISR heraus zugegriffen wird und das dann nötige volatile 
fehlt?

von Nerb (Gast)


Lesenswert?

Hi,

ja, die if-Abfrage sitzt in einer ISR, nur funktioniert das 
Schlüsselwort volatile auch nicht. Ich habe mal die Werte der Variable 
geändert, daraus ergab sich, dass in der ISR immer eine neue Variable 
mit diesem Namen erzeugt wird. Wenn ich extern wegnehme, dann 
funktioniert ja alles. Ich schätze, das fügt der Compiler dann zusammen 
und macht es dann aber richtig, obwohl das nicht c-konform ist...

Grüße,
Philip

von Karl H. (kbuchegg)


Lesenswert?

Nerb schrieb:
> Hi,
>
> ja, die if-Abfrage sitzt in einer ISR, nur funktioniert das
> Schlüsselwort volatile auch nicht.

Es kann natürlich sein, dass da jetzt mehrere Probleme zusammenspielen.

> Ich habe mal die Werte der Variable
> geändert, daraus ergab sich, dass in der ISR immer eine neue Variable
> mit diesem Namen erzeugt wird.

Ganz sicher nicht.
Wenn das eine globale Variable ist, dann gibt es sie auch nur 1 mal.

> Wenn ich extern wegnehme, dann
> funktioniert ja alles.

Irgendwie klingt das für mich als ob du nach dem Muster "Ich probier 
einfach so lang rum, bis ich was habe, das so aussieht, als ob es 
funktioniert" arbeitest.
Das hat noch nie funktioniert und das wird auch nie funktionieren. Gut 
gelerntes C, bei dem man auch im Detail weiß, was die Anweisungen 
bewirken, warum es sie gibt und wie die Regeln zu ihrer Verwendung sind, 
ist durch nichts zu ersetzen.
Das das nicht von heute auf morgen geht, ist auch klar. Es dauert nun 
mal Jahre, bis man das Zusammenspiel auch in den Details versteht. 
Optimierer abschalten versteckt nur die Probleme (in den meisten Fällen. 
Natürlich gibt es auch Fehler im Compiler bzw. Optimierer. Die sind aber 
selten).


> Ich schätze, das fügt der Compiler dann zusammen
> und macht es dann aber richtig, obwohl das nicht c-konform ist...

Auf eines kannst du wetten: Auch wenn nicht alle Compiler zu 100% 
Standard-konfoem sind - sie verstehen immer noch mehr von Konformität 
zum C-Standard als mehr als 80% aller C-Programmierer. Vor allen Dingen 
diejenige, die nie systematisch durch den zu erlernenden Sprachumfang 
geführt wurden, diejenigen die meinen mit einem windigen Tutorial würde 
das schon reichen, vor allem die zeichnen sich regelmässig durch 
unglaublich große Wissenslücken aus. Kein Mensch weiß alles, aber das 
Wissensgefälle ist schon augenscheinlich.


Zeig doch mal etwas mehr Code - mehr Details. Dann findet sicher auch 
hier im Forum jemand die problematischen Dinge.


Schuss ins Blaue
global.h
1
extern volatile uint8_t globaleVariable;

global.c
1
volatile uint8_t globaleVariable = 0;

Und dann darauf achten, dass dein Makefile in Ordnung ist und 
tatsächlich auch wirklich alles neu compiliert wird.

von Εrnst B. (ernst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Zeig doch mal etwas mehr Code - mehr Details. Dann findet sicher auch
> hier im Forum jemand die problematischen Dinge.

Ich tipp drauf dass:

Nerb schrieb:
> transceive.c
> #include "global.h"
> if(globaleVariable == 1)
> {
>     Dieser Code wird nicht aufgefuehrt, wenn ich optimiere.
> }


sowas ist:
1
ISR(xxx) {
2
#include "global.h"
3
  if (globaleVariable==1)... {
4
 ...
5
  }
6
}


der Präprozessor macht daraus etwas wie
1
  void __vector_xxx() {
2
    int globaleVariable; // aber eher lokal
3
    if (globableVariable == 1) { // zurecht wegoptimiert
4
5
    }
6
  }

von Nerb (Gast)


Lesenswert?

Hi,

es tritt genau das Verhalten auf, das Ernst B beschrieben hat, in der 
ISR wird eine neue Variable erzeugt, die uninitialisiert bleibt. Nur 
habe ich die global.h vor dem ISR Block eingefügt.

Mehr vom Code zu zeigen, würde nicht viel helfen, der ist schon 6k loc 
lang. Das gezeigte Beispiel beschreibt das Problem ganz gut.

Momentan sieht mein Programm so aus (etwas verfeinert)

 global.h
1
extern volatile char globaleVariable;

global.c
1
char globaleVariable = 'h';

transceive.c
1
#include "global.h"
2
ISR(vektorXY)
3
{
4
   switch(globaleVariable)
5
   {
6
   case 'h': Dieser Code wird nicht aufgefuehrt, wenn ich optimiere. break;
7
   case 'n': Dieser Code wird nicht aufgefuehrt, wenn ich optimiere. break;
8
   }
9
}

func.c
1
#include <avr/eeprom.h>
2
void load_config()
3
{
4
    globaleVariable = (char)eeprom_read_byte(&ee_globaleVariable);;
5
}

Als Mikrocontroller benutze ich einen XMega, dazu AVR Studio 6 mit gcc.

Danke für eure Hilfe.


Grüße,
Philip

von Falk B. (falk)


Lesenswert?

@  Nerb (Gast)

>es tritt genau das Verhalten auf, das Ernst B beschrieben hat, in der
>ISR wird eine neue Variable erzeugt, die uninitialisiert bleibt. Nur
>habe ich die global.h vor dem ISR Block eingefügt.

Dan stimmen deine Definitionen nicht.

>Mehr vom Code zu zeigen, würde nicht viel helfen,

Du musst es wissen.

> der ist schon 6k loc
>lang.

Es gibt die Funktion, das als Anhang zu sendne.

> Das gezeigte Beispiel beschreibt das Problem ganz gut.

Und ist nur eine unzulängliche Kopie. Fail, wie es so schön auf 
Neudeutsch heißt.

http://www.mikrocontroller.net/articles/Netiquette#.C3.84u.C3.9Fere_Form

"Quelltext nie abtippen, sonder immer das direkt kopierte Original 
posten, anderenfalls schleichen sich neue Fehler ein oder die 
existierenden werden nicht abgeschrieben."

von xfr (Gast)


Lesenswert?

Versuch es in global.c mal mit:
1
volatile char globaleVariable = 'h';

von xfr (Gast)


Lesenswert?

xfr schrieb:
> Versuch es in global.c mal mit:volatile char globaleVariable = 'h';

Obwohl, optimiert wird ja in den anderen Dateien, die nur das 
Header-File sehen. Das ist es also wahrscheinlich nicht. Schaden würde 
es aber trotzdem ist.

von Jens (Gast)


Lesenswert?

Moin,

mal angenommen, es ist richtig abgetippt, dann sollte die Deklaration 
der Variable auch das volatile enthalten...

von Karl H. (kbuchegg)


Lesenswert?

Nerb schrieb:

> Mehr vom Code zu zeigen, würde nicht viel helfen, der ist schon 6k loc
> lang.

:-)
Aha. Die wesentlich wahrscheinlichere Variante ist allerdings, dass in 
deinen 6k loc irgendwo anders ein Fehler ist und du dir die globale 
Variable über den Haufen schiesst (so zu sagen).

Aber bitte. Wenn du nicht herzeigen willst, dann eben nicht.
Such weiter deinen Fehler an einer Stelle, an der kein Fehler ist.

Was du siehst, ist das Symptom.
Die Ursache kann aber ganz woanders im Code sitzen.

von Fred S. (kogitsune)


Lesenswert?

Woher weißt Du, dass der Code bei Optimierung nicht ausgeführt wird? 
Steht dort etwas, dass mit Sicherheit auf Variablen (oder Register) 
zugreift, die bestimmt nicht wegoptimiert werden? Hast Du mal in die 
Assembler-Listings mit Optimierung im Vergleich zu ohne Optimierung 
verglichen?

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.