Optimierung verstehen

Gast #5326652
Lesenswert?

Hallo,
bin Anfänger auf dem Gebiet, also haut mich nicht gleich.

Ich hab das Problem, dass GCC mir das weg optimiert:
1
U08 msg_new[msgSize];
2
U08 i;
3
  
4
uint8_t address = msg[0];
5

6
for(i=0; i<msgSize; i++)
7
{
8
  msg_new[i] = msg[i+1];
9
}

Optimierung steht auf: -O0
Wenn ich die Optimierung ausschalte geht es.
Aber warum wird es weg optimiert?
Und wie kann ich es verhindern, ohne komplett die Optimierung 
ausschalten zu müssen.

Danke
Gast #5326660
Lesenswert?

AVR Beginner schrieb im Beitrag #5326652:
> Aber warum wird es weg optimiert?

Weil es nicht gebraucht wird oder der Compiler das nicht weiss.
Wo und wie ist msg[] deklariert?
Wie sieht dein wahrer, vollständiger Minimal-Code aus, bei dem dein 
Problem auftritt?
Was genau ist überhaupt dein Problem?
Gast #5326672
Lesenswert?

Wolfgang schrieb:
> Wo und wie ist msg[] deklariert?

Sorry vergessen:
1
unsigned char msg[msgSize];
Wolfgang schrieb:
> Weil es nicht gebraucht wird

Ich will es aber haben.

Wolfgang schrieb:
> Wie sieht dein wahrer, vollständiger Minimal-Code aus, bei dem dein
> Problem auftritt?

Verstehe nicht ganz.
Ich will ein Array um eins nach links verschieben.
Geht das auch einfacher?
#5326680
Lesenswert?

Deine Schleife geht bis i<msgSize.
In der Schleife greifst Du aber lesend noch auf msg[i+1] zu, also ein 
Element "hinter" Deinem msg Array. Das ist nicht definiert. Da es aber 
nur lesend ist, dürfte dabei nichts schlimmeres passieren, als dass Du 
einen Quatsch-Wert erhältst. Das sollte aber mit Deiner eigentlichen 
Fragestellung nichts zu tun haben.
Gast #5326688
Lesenswert?

AVR Beginner schrieb im Beitrag #5326678:
> Frank M. schrieb:
>> Warum benutzt Du dann 2 verschiedene Arrays?
>
> Stimmt, ich könnte es auch im selben machen, danke.

Habs mal mit einem Array gemacht, wird auch weg optimiert, warum?
Lasst mich nicht dumm sterben.
Moderator Persönliche Seite #5326700
Lesenswert?

AVR Beginner schrieb im Beitrag #5326688:
> Habs mal mit einem Array gemacht, wird auch weg optimiert, warum?

Glaube ich nicht, aber mit ein- und demselben Array hast Du dann einen 
Fehler:
1
U08 msg[msgSize];
2

3
for(i=0; i<msgSize; i++)
4
{
5
  msg[i] = msg[i+1];
6
}

Wenn beim letzten Schleifendurchlauf i = msgSize - 1 ist, dann greift 
msg[i+1] ins Klo.

Richtig wäre:
1
U08 msg_new[msgSize];
2

3
for(i = 0; i < msgSize - 1; i++)    // Eins weniger kopieren!
4
{
5
  msg[i] = msg[i + 1];
6
}

Was soll dann mit dem letzten Member von msg passieren? Auf 0 setzen?
Gast #5326708
Lesenswert?

Frank M. schrieb:
> Wenn beim letzten Schleifendurchlauf i = msgSize - 1 ist, dann greift
> msg[i+1] ins Klo.
>
> Richtig wäre:
> U08 msg_new[msgSize];
>
> for(i = 0; i < msgSize - 1; i++)    // Eins weniger kopieren!
> {
>   msg[i] = msg[i + 1];
> }

Aber bei i=msgSize wird doch die Schleife gar nicht mehr ausgeführt, 
oder ist das falsch?
Gast #5326711
Lesenswert?

AVR Beginner schrieb im Beitrag #5326688:
> Habs mal mit einem Array gemacht, wird auch weg optimiert, warum?

Meine Glaskugel sagt:
Die Veränderung passiert in einer ISR.
Aber die Variablen sind nicht volatile.

Also:
Da wird nichts weg optimiert.


// ---------

Meine Glaskugel sagt:

Das ist sowieso der erste Gedanke, der auf den Müll gehört!
> wegoptimiert

Der Compiler optimiert nichts wichtiges weg.
Never.
Vielleicht gibts Probleme mit (kaputtoptimierten) Zeitschleifen, aber 
nicht mit der Funktion/Logik.

Der Fehler liegt woanders.
Moderator Persönliche Seite #5326714
Lesenswert?

AVR Beginner schrieb im Beitrag #5326708:
> Aber bei i=msgSize wird doch die Schleife gar nicht mehr ausgeführt,
> oder ist das falsch?

Korrekt, aber bei i = msgSize - 1 wird sie noch ausgeführt und
1
msg[i+1] identisch mit msg[msgSize - 1 + 1] identisch mit msg[msgSize]

ist dann nicht mehr definiert, denn Dein Array geht nur von 0 bis 
msgSize - 1.

Konkret: Von 100 Werten kannst Du nur 99 nach links schieben.
Gast #5326719
Lesenswert?

Frank M. schrieb:
> AVR Beginner schrieb im Beitrag #5326708:
>> Aber bei i=msgSize wird doch die Schleife gar nicht mehr ausgeführt,
>> oder ist das falsch?
>
> Korrekt, aber bei i = msgSize - 1 wird sie noch ausgeführt undmsg[i+1]
> identisch mit msg[msgSize - 1 + 1] identisch mit msg[msgSize]
>
> ist dann nicht mehr definiert, denn Dein Array geht nur von 0 bis
> msgSize - 1.

Hast recht. hat aber keine Auswirkung auf die Optimierung.
Gast #5326720
Lesenswert?

AVR Beginner schrieb im Beitrag #5326710:
> Ich arbeite später doch mit den Variablen weiter.

Bist du sicher, dass das die selbe Variable ist?
Der Compiler optimiert die Variable nicht weg, wenn er sieht, dass du 
drauf zugreifst.

Wie sieht dein Code wirklich aus?
Moderator Persönliche Seite #5326726
Lesenswert?

AVR Beginner schrieb im Beitrag #5326721:
> Kann ich dem Compiler nicht irgendwie sagen, dass er den Codeteil nicht
> weg optimieren soll?

Wie gesagt: Ich glaube es nicht, dass der Code wegoptimiert wird - 
jedenfalls dann, wenn Du ein- und dasselbe Array verwendest und Du 
danach noch drauf zugreifst.

Zeige den kompletten Source und zeige genau die Stelle, an der Du 
angeblich merkst, dass der Code wegoptimiert ist! So ist das ein 
Stochern im Dunkeln!
Moderator Persönliche Seite #5326730
Lesenswert?

Jim M. schrieb:
> Weil das hier ein Fall memmove() ist.

memmove auf einem µC ist suboptimal. Aus dem Manual:
1
The memmove() function copies n bytes from memory area src to memory area dest. The memory areas may overlap: copying takes place as though the bytes in src are first copied into a temporary array that does not overlap src or dest, and the bytes are then copied from the temporary array to dest.

Das per malloc() allokierte Array willst Du auf einem µC nicht.
Gast #5326733
Lesenswert?

Frank M. schrieb:
> Zeige den kompletten Source und zeige genau die Stelle, an der Du
> angeblich merkst, dass der Code wegoptimiert ist! So ist das ein
> Stochern im Dunkeln!
1
void TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize)
2
{  
3
  U08 i;
4
    
5
  uint8_t address = msg[0];
6

7
  for(i=0; i<msgSize-1; i++)
8
  {
9
    msg[i] = msg[i+1];
10
  }
11

12
  TWI_MasterWrite(&twiMaster, address, msg , msgSize-1);
13
}

[Mod: C-Formatierung eingebaut]
Gast #5326741
Lesenswert?

Jim M. schrieb:
> Weil das hier ein Fall memmove() ist.

Bitte bemerke:
Anfangs war von 2 Arrays die Rede.

Wenn sich zwischendurch der Kontext ändert, solltest du das nicht mir 
ankreiden.


Aber da schon memcpy() nicht bekannt war, glaube ich dass der Bock ganz 
woanders zu suchen ist.
Den da liegt noch viel mehr im Nebel.
Moderator Persönliche Seite #5326743
Lesenswert?

Ralf schrieb:
> Es kam schon mal der Vorschlag : Ringbuffer!

Ringbuffer wäre hier absoluter Blödsinn, an msg[0] steht der Wert von 
address - ganz einfach.

An den TO: Du brauchst den Buffer überhaupt nicht nach links kopieren. 
Für Deine Anforderung kannst Du das viel einfacher erledigen:
1
void TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize)
2
{  
3
    TWI_MasterWrite(&twiMaster, msg[0], msg + 1,  msgSize - 1);
4
}

Dein Vorhaben reduziert sich also auf einen Einzeiler. Hier wird einfach 
ein Pointer ab der Stelle msg + 1 übergeben.

P.S.
Formatiere bitte zukünftig Deinen Code hier mit
1
[c] code [/c]

Dann wird das lesbarer. Ich habe das oben mal für Dich gemacht.
Gast #5330212
Lesenswert?

Michael R. schrieb:
> ann liegt dein Fehler wo anders und durch das Einschalten der
> Optimierung killst du wo anders das Verhalten deines Codes...

Wenn ich den Debugger anschließe, dann sagt er mir aber genau in dieser 
for-Schleife "optimized away".
Dann gibt es doch dort ein Problem, oder nicht?
An dieser I2C Schnittstelle hängt ein Display. Es zeigt Zeichen an, wenn 
die Optimierung aus ist. Sobald ich eine einschalte geht es nicht mehr.

Wie kann ich es heraus finden, wo es noch sonst noch hakt?
Gast #5330298
Lesenswert?

AVR Beginner schrieb im Beitrag #5330212:
> Dann gibt es doch dort ein Problem, oder nicht?

Nicht unbedingt.
Du siehst da nur die Handgranate hoch gehen.

Die Wirkung.
Die Ursache ist woanders.

Tipp:
> Der Weg in die Hölle ist mit falschen Annahmen gepflastert.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren