Forum: Compiler & IDEs Detected loop counting up. Recommend loops count down as detecting zeros is easier


von Info (Gast)


Lesenswert?

Der TI MSP430 Compiler sagt zu diesem Code
1
uint16_t i;
2
for (i=0; i<14; i++){
3
  function( array[i] );
4
}

> Detected loop counting up. Recommend loops count down as detecting zeros is 
easier

Lässt er sich beruhigen, ohne die Daten im Array umzudrehen?

von (prx) A. K. (prx)


Lesenswert?

Info schrieb:
> Lässt er sich beruhigen, ohne die Daten im Array umzudrehen?

Gegen perverse Compiler hilft vielleicht perverser Code:
1
int16_t i;
2
for (i=-14; i!=0; i++){
3
  function( array[14+i] );
4
}

von Info (Gast)


Lesenswert?

;-)

Danke dir, mal sehen, ob ich irgendwie an das Resultat herankomme.
Und ob ihm eine Subtraktion des Index besser schmeckt.

Oder ich ignoriere ihn und konzentriere mich auf's Programm..

von Mario M. (thelonging)


Lesenswert?

Die einzige Konsequenz ist, dass die Schleife pro Durchlauf einen Takt 
mehr benötigt. TI empfiehlt die Optimierung auf "-o2" zu setzen.

http://processors.wiki.ti.com/index.php/Compiler/diagnostic_messages/MSP430/1544

von Info (Gast)


Lesenswert?

Danke für den Link.

von Eric B. (beric)


Lesenswert?

1
uint16_t i;
2
uint8_t *parr = array;
3
4
for(i = 14; i > 0; i--) {
5
  function(parr);
6
  parr++;
7
}

von Max G. (l0wside) Benutzerseite


Lesenswert?

Sorry, das ist Quark und dient nur dazu, den Hinweis abzustellen. Du 
sparst jeweils einen Takt, musst aber den wieder spendieren, um die 
Addition von *parr zu rechnen. Und verbrauchst außerdem ein Wort extra.

Außerhalb von zeitkritischen ISRs kann man den Hinweis i.d.R. getrost 
ignorieren. Dafür sollte man sich beim Optimieren genau anschauen, was 
der Compiler treibt. Der TI-Compiler ist alles andere als fehlerfrei :(

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Max G. schrieb:
> Sorry, das ist Quark und dient nur dazu, den Hinweis abzustellen. Du
> sparst jeweils einen Takt, musst aber den wieder spendieren, um die
> Addition von *parr zu rechnen. Und verbrauchst außerdem ein Wort extra.

Wobei solche Kalkulationen auf Hochsprachenbasis nicht notwendigerweise 
dem entsprechen, was hinten aus dem Compiler rauskommt. Hochoptimierende 
Compiler wie GCC erzeugen in beiden Beispielen den gleichen Code (bei 
-O2).

Ob also ein Index im Quelltext inkrementiert oder dekrementiert wird ist 
ihm egal, im erzeugten Code gibt es keinen Index, statt dessen wird in 
beiden Fällen ein Pointer inkrementiert und verglichen. Entspricht:
  uint8_t *parr = array;
  do {
    function(*parr);
  } while (++parr != array+14);

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Ein Compiler der sagt:
"Ich weiss was Du willst, bin aber zu blöd, das in Assembler umzusetzen. 
Bitte hilf mir".
Naja, wenigstens ehrlich, die Entwickler!

von (prx) A. K. (prx)


Lesenswert?

Achim S. schrieb:
> "Ich weiss was Du willst, bin aber zu blöd, das in Assembler umzusetzen.
> Bitte hilf mir".

Nö. Er sagt: "Du hast mir nicht erlaubt, wirklich zu optimieren, also tu 
es gefälligst selbst". Mit "-o2" macht er es.

von meckerziege (Gast)


Lesenswert?

Darfst du denn überhaupt die Reihenfolge des Durchlaufs umdrehen? Was 
macht denn function(.)?

Falls function(.) frei von Seiteneffekten ist und dessen Output nur von 
den Eingangswerten abhängt, dann gebe ihr das Attribut "pure". DANN darf 
der Compiler das auch selbst umdrehen. (ob er es macht, ist eine andere 
Frage. Da spielen noch mehr sachen mit rein).

von (prx) A. K. (prx)


Lesenswert?

meckerziege schrieb:
> Darfst du denn überhaupt die Reihenfolge des Durchlaufs umdrehen? Was
> macht denn function(.)?

Die Reihenfolge der Funktionsaufrufe darf er normalerweise nicht 
umdrehen (Ausnahmen siehe z.B. meckerziege, oder bei Inlining). Die 
Werteabfolge einer Zählvariablen hingegen schon, wenn das keine 
Auswirkung auf die Reihenfolge der Funktionsaufrufe oder anderen Code 
hat, weil er für das Array eine andere Lösung hat. Ebenso kann er die 
Zählvariable selbst komplett eliminieren.

Der Code im Startbeitrag ist eine klassische Zählschleife mit Verwendung 
als Index. Ein guter Compiler wird darin erkennen, dass die Schleife 14x 
ausgeführt wird und das Array aufsteigend ab 0 indiziert wird. Wie er 
das dann implementiert ist allein seine Sache, da die Zählvariable 
nirgends sonst verwendet wird (wobei ich annehme, sie ist lokal 
definiert, nicht global).

Daumenregel: Wenn als Ergebnis von erzeugten Code das rauskommt, was 
unter Anwendung der Regeln von C rauskommen darf, darf er machen was er 
will. Wobei mit und ohne Optimierung auch verschiedene Ergebnisse 
rauskommen dürfen, wenn beide in diesem Sinn zulässig sind.

: Bearbeitet durch User
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.