C & amp; C ++ - Compiler können Operationen neu anordnen, solange die as-if -Regel gilt. Was ist ein Beispiel für eine solche Neuordnung, die von einem Compiler durchgeführt wird, und was ist der potenzielle Leistungsgewinn, der dadurch erreicht werden kann?
Beispiele, die einen (C / C ++) Compiler auf einer beliebigen Plattform beinhalten, sind willkommen.
Angenommen, Sie führen die folgenden Vorgänge aus:
%Vor% Wenn Sie in dem Moment ignorieren, dass die drei Inkremente wahrscheinlich vom Compiler in ein +=3
entfernt werden, haben Sie einen höheren Prozessor-Pipeline-Durchsatz, wenn Sie die Operationen als
da j++
nicht auf das Ergebnis von i++
warten muss, während im vorherigen Fall die meisten Anweisungen eine Datenabhängigkeit von der vorherigen Anweisung hatten. Bei komplizierteren Berechnungen, bei denen es keine einfache Möglichkeit gibt, die Anzahl der auszuführenden Befehle zu reduzieren, kann der Compiler immer noch Datenabhängigkeiten betrachten und Befehle neu anordnen, so daß ein von dem Ergebnis eines früheren Befehls abhängiger Befehl so weit entfernt ist daraus wie möglich.
Ein weiteres Beispiel für eine solche Optimierung ist, wenn Sie mit reinen Funktionen arbeiten. Schauen wir uns ein einfaches Beispiel an und nehmen wir an, Sie haben eine reine Funktion f(int x)
, die Sie über eine Schleife summieren.
Da f
eine reine Funktion ist, kann der Compiler die Aufrufe anordnen, wie es ihm gefällt. Insbesondere kann diese Schleife in
Ich bin mir sicher, dass es einige Beispiele gibt, bei denen das Nachbestellen zu einer schnelleren Leistung führt. Ein naheliegendes Beispiel wäre, Ladevorgänge so früh wie möglich neu zu ordnen, da diese normalerweise viel langsamer als andere CPU-Vorgänge sind. Durch andere, nicht verwandte Arbeit, während der Speicher geholt wird, kann die CPU insgesamt Zeit sparen.
Das heißt, in etwa so:
%Vor%Wir können es wie folgt neu anordnen:
%Vor% Während wir darauf warten, dass der Ladevorgang abgeschlossen ist, können wir expensive_calculation()
kostenlos ausführen.
Angenommen, Sie haben eine Schleife wie:
%Vor% Denken Sie an memcpy
. Möglicherweise möchten Sie, dass der Compiler dies vektorisiert, d. H. 8 oder 16 Bytes gleichzeitig lädt und dann 8 oder 16 gleichzeitig speichert. Diese Umwandlung ist eine Neuordnung, da src[1]
gelesen wird, bevor dest[0]
gespeichert wird. Solange der Compiler nicht weiß, dass sich src
und dest
nicht überschneiden, ist es eine ungültige Umwandlung , d. H. Eine, die der Compiler nicht ausführen darf. Mit dem Schlüsselwort restrict
(C99 und höher) können Sie dem Compiler mitteilen, dass sie sich nicht überschneiden, damit diese (äußerst wertvolle) Optimierung möglich ist.
Die gleiche Art von Ding entsteht die ganze Zeit in Operationen auf Arrays, die nicht nur kopieren - Dinge wie Vektor / Matrix-Operationen, Transformationen von Sound / Bild-Sample-Daten, etc.
Tags und Links c c++ compiler-optimization