warum ++i performanter als i++
-
knivil schrieb:
es heißt ja immer, ++i sei performanter.
Quatsch. Schau dir doch mal bitte an: http://isocpp.org/blog/2012/12/three-optimization-tips-alexandrescu
In Kombination mit Arrays kann Zugriff und Inkrement in der Pipeline parallel/out of order abgearbeitet werden:
array[i++] = 54Da wird der Compiler doch selber drauf kommen?
-
Ich mag i++ nicht. Immer wenn ich es sehe, frage ich mir, wozu brauchst du hier den alten Wert? weißt du nicht was Post-Inc/Dec macht oder willst du mich nur in die Irre führen?... Außerdem find ich Post-Inc/Dec inkonsistent.
-
Ethon schrieb:
Da wird der Compiler doch selber drauf kommen?
Wie meinst du das? Auf was soll der Kompiler kommen?
Ich mag i++ nicht.
Ja, tolle Begruendung.
Immer wenn ich es sehe, frage ich mir, wozu brauchst du hier den alten Wert?
Nun, schon mal Standardimplementierungen von memcpy/strcpy gesehen?
-
knivil schrieb:
In Kombination mit Arrays kann Zugriff und Inkrement in der Pipeline parallel/out of order abgearbeitet werden:
array[i++] = 54Ist bei Präinkrement nicht anders, sofern der Prozessor über geeignete Adressierungsmodi verfügt.
-
knivil schrieb:
Ethon schrieb:
Da wird der Compiler doch selber drauf kommen?
Wie meinst du das? Auf was soll der Kompiler kommen?
Liege ich gerade falsch oder geht es darum dass der Array-Zugriff mit Postinkrement schneller ist?
Falls das stimmt, wird der Compiler doch wohl schlau genug sein bzw die CPU hinreichend kennen und die performantere Methode wählen, wenn es keinen Einfluss auf das Programmverhalten hat.
-
Ist bei Präinkrement nicht anders, sofern der Prozessor über geeignete Adressierungsmodi verfügt.
Also bei
array[++i] = 45Soll er i inkrementieren und parallel an die Adresse mit dem neuen i schreiben?
wird der Compiler doch wohl schlau genug sein
Was schneller ist, weiss ich nicht, da ich nicht gemessen habe. Aber prinzipiell sollte der Compiler schon den Quelltext beruecksichtigen, den ich hinschreibe.
PS: Das Video dient als Referenz. D.h. ich habe nichts selbst gemessen oder ausprobiert.
-
knivil schrieb:
Ich sehe schon, dass niemand das Video sich angesehen hat. Anscheinend wars bei Facebook anders.
Ich hab mir die verlinkten Slides des Vortrags angeschaut. Der Vortrag ist mir gerade zu lang.

-
Ethon schrieb:
Ich hab mir die verlinkten Slides des Vortrags angeschaut. Der Vortrag ist mir gerade zu lang.

Ja, das ist er.
-
knivil schrieb:
Ist bei Präinkrement nicht anders, sofern der Prozessor über geeignete Adressierungsmodi verfügt.
Also bei
array[++i] = 45Soll er i inkrementieren und parallel an die Adresse mit dem neuen i schreiben?
Der Schreibzugriff hängt nur scheinbar von der Inkrementierung von i ab.
array[++i]ist
*(array + ++i)ist
*(array + (i+=1))ist
*(array + iold + 1) und inew = iold + 1
ist
*((array + 1) + iold) und inew = iold + 1
sofern array statische Lebensdauer hat, kann die Erhöhung bereits beim Compilieren direkt berücksichtigt werden, ansonsten helfen Adressierungsmodi mit festem Displacement, über die praktisch jeder moderne Prozessor verfügt.
-
knivil schrieb:
Aber prinzipiell sollte der Compiler schon den Quelltext beruecksichtigen, den ich hinschreibe.
Hmm, wenn ich
if(x % 2 == 0)schreibe, der Compiler aber weiß dass meine CPU ein AND schneller ausführt als ein MOD und daraus
if(x & 1 == 0)macht, dann bin ich aber froh.
Ist imho das Gleiche wie bei den unterschiedlichen Inkrementierungsoperatoren.
-
Ethon schrieb:
Ist imho das Gleiche wie bei den unterschiedlichen Inkrementierungsoperatoren.
Nein, weil bei deinem Beispiel keine Seiteneffekte auftreten.
kann die Erhöhung bereits beim Compilieren direkt berücksichtigt werden
Nun, ich bin mir unsicher, ob der Compiler beispielsweise array einfach mit einem anderen Wert initialisiert. Und eine Zeile Code ist auch ein schlechtes Beispiel.
Adressierungsmodi mit festem Displacement
Meinst du, dass einfach eine Konstante in den Befehl mitkodiert wird? Kann mir gerade nicht so viel drunter vorstellen.
-
knivil schrieb:
Adressierungsmodi mit festem Displacement
Meinst du, dass einfach eine Konstante in den Befehl mitkodiert wird? Kann mir gerade nicht so viel drunter vorstellen.
Genau das.
-
Man kann sich raussuchen, was man da generell macht, wenn es nicht drauf ankommt; das sollte nur konsistent gemacht werden und nicht mal so, mal so. Ich hab mir preincrement für alle Standard-Fälle angewöhnt. Andere nehmen postincrement.
Herb Sutter
schreibt (als Richtlinie, nicht als Pflicht):Guideline
Prefer preincrement. Only use postincrement if you're going to use the original value.Und weiter unten:
... Is the compiler allowed to notice this and simply rewrite the postincrement as preincrement as an optimization?
The answer is: No, not in general. The only time the compiler is allowed to optimize away unnecessary postincrement by rewriting it as preincrement is for builtin and standard types, such as
intandcomplex, whose semantics the compiler is allowed to know because they're standard.For class types, on the other hand, the compiler can't know the actual semantics of postincrement and preincrement--indeed, the two actually might not do the same thing. It would be a terrible thing indeed if the two functions didn't have the same semantics, and any programmer who wrote them with different semantics should be sacked on the spot. But, in general, that doesn't help the compiler, because it can't assume that the programmer is consistent.