Forum: PC-Programmierung Compiler optimiert Zählschleife weg


von Daniel (Gast)


Lesenswert?

Hallo,

habe gerade ein paar Testzeilen auf dem TI Launchpad laufen lassen. Ich 
wollte lediglich die LED blinken lassen und habe deswegen geschrieben:

while (1) {
   P1OUT ^= BIT0;
   unsigned short i = 50000;

   do{
      i--
   } while (i);
}

Die LED blinkt zwar, aber viel zu schnell. Erst wenn ich die Variable i 
als volatile markiere, läuft das Programm so, wie es soll. Dieses 
Verhalten ist mir noch nie aufgefallen. Ist dieses wegoptimieren ein 
"Feature" des TI-Compilers oder habe ich in der C-Vorlesung tatsächlich 
etwas verpennt?


Viele Grüße

Daniel

von (prx) A. K. (prx)


Lesenswert?

Ist völlig normal und zulässig. Die Schleife hat keinerlei für den 
Compiler erkennbare Auswirkungen, abgesehen davon dass sie mit i==0 
beendet wird, und wird folglich rausgeworfen und durch i=0 ersetzt - was 
dann mangels weiterer Verwendung von i ebenfalls rausfliegt. "i" 
volatile deklarieren, oder es gleich mit Delay-Routinen richtig machen.

von Daniel (Gast)


Lesenswert?

A. K. schrieb:
> Ist völlig normal und zulässig. Die Schleife hat keinerlei für den
> Compiler erkennbare Auswirkungen, abgesehen davon dass sie mit i==0
> beendet wird, und wird folglich rausgeworfen und durch i=0 ersetzt - was
> dann mangels weiterer Verwendung von i ebenfalls rausfliegt. "i"
> volatile deklarieren, oder es gleich mit Delay-Routinen richtig machen.

Okay thx. Ich habe zwar bei vier Quellen nachgesehen, aber da wurde das 
nur immer für ISR so erklärt. Gut zu wissen, dass ein Compiler 
heutzutage schon so kleinlich ist^^

von nocheinGast (Gast)


Lesenswert?

Das ist nicht kleinlich, sondern sinnvoll, schließlich soll er das 
Programm optimieren, damit es möglichst schnell wird...

von Daniel (Gast)


Lesenswert?

nocheinGast schrieb:
> Das ist nicht kleinlich, sondern sinnvoll, schließlich soll er das
> Programm optimieren, damit es möglichst schnell wird...

I komm net auf der Brennsuppn dahergschwommen. Man beachte das "^^"

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Daniel schrieb:
> Ich habe zwar bei vier Quellen nachgesehen, aber da wurde das
> nur immer für ISR so erklärt. Gut zu wissen, dass ein Compiler
> heutzutage schon so kleinlich ist

Genaugenommen nicht der Compiler, sondern der Sprachstandard.

Der Compiler übersetzt die Quelle gemäß der Spachspezifikation. Nicht 
mehr und nicht weniger.

Diese Abbildung
   Quelle → Programm
ist nicht eindeutig und kann auf unterschiedliche Art und Weise 
erfolgen. IdR wird eine Abbildung bevorzugt, die resourcensparend ist.

Da eine Schleide wie oben keine "Wirkung auf die Welt" halt, also auf 
das, was im C-Standard "abstrakte Maschine" genannt wird", kann es 
einfach weggelassen werden, ohne die Semantik des Programms zu ändern.

von Rolf Magnus (Gast)


Lesenswert?

Naja, prinzipiell sagt die C-Norm schon, daß im obigen Code i mit 50000 
initialisiert und dann so oft dekrementiert wird, bis es 0 ist. Daß der 
Compiler das hier abkürzen kann, liegt an der so genannten "as-if rule", 
die für Optimierungen essenziell ist. Diese besagt, daß der Compiler den 
Code beliebig verändern darf, solange sich das "observable behavior", 
also das beobachtbarte Verhalten dadurch nicht ändert. Dieses Verhalten 
ist definiert durch File-I/O und den Zugriff auf volatile-Variablen. 
Deshalb ändert sich das Verhalten auch, wenn du die Zählvariable 
volatile machst. Jeder einzelne Zugriff auf die Variable, der im 
Quellcode steht, muß dann auch tatsächlich auf der Hardware durchgeführt 
werden.

von (prx) A. K. (prx)


Lesenswert?

Was zu der paradox erscheinenden Situation führt, dass
1
while(1) { }
als Totschleife drin gelassen werden muss, während die in ihrer 
praktischen Auswirkung eigentlich gleich wirkende Schleife
1
for (int128_t i = INT128_MAX; i != 0; --i) { }
komplett entsorgt werden darf. Manchmal sind Compiler eben Theoretiker.

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.