2016-05-22 24 views
1

In x86-64 verwenden:Stoppt die x86-64-Pipeline auf einem indirekten Sprung wie JMP RAX? Wenn Sie den folgenden Assembler-Code

MOV RAX, (memory address) 
JMP RAX 

Ist die Pipeline Stall vor der Verzweigung ausgeführt wird (um MOV zu warten mit RAX bis Ende), oder es wird die Pipeline wie ein bedingter bündig Ast?

+0

Selbst falsch vorhergesagte bedingte Verzweigungen müssen die Pipeline in modernen Designs nicht vollständig leeren. Die Pipeline kann die korrekte Arbeit behalten, die sie für Anweisungen vor dem falsch vorhergesagten Zweig geleistet hat. Dies gilt für die Intel SnB-Familie und vielleicht Core2; Ich vergesse, aber [Agner Fogs Mikroarch Leitfaden könnte sagen] (http://agner.org/optimize) –

Antwort

4

Für die meisten modernen 80x86 CPUs; Es gibt eine statische Vorhersage (keine Historie, die verwendet werden kann, um eine bessere Vorhersage zu treffen) und eine dynamische Vorhersage (wobei der Verlauf von vorherigen Ausführungen verwendet werden kann).

Für die statische Vorhersage sagt die CPU voraus, dass die Ausführung an der Anweisung unmittelbar nach der JMP RAX fortgesetzt wird. Ich bin mir nicht ganz sicher, welche CPUs die dynamische Vorhersage für JMP RAX verwenden (anstatt nur für die Jc Zweige); aber für diejenigen, die dies tun, würde es die statische Vorhersage überschreiben.

Sobald die CPU eine vorhergesagte Zieladresse hat, wird sie spekulativ ausgeführt, bis sie erkennt, ob sie richtig/falsch vorhergesagt hat. Wenn es richtig vorhergesagt hat, behält es seine ganze Arbeit bei und die JMP RAX hätte wenig oder keine Kosten.

Wenn die CPU falsch vorhergesagt hat, ist das nicht anders als bei jeder anderen Verzweigungsfehlvorhersage (verwerfen Sie alle Arbeiten, die spekulativ ausgeführt wurden, und gehen Sie zurück zum Fetch/Decodieren beim richtigen RIP).

Beachten Sie, dass wenn Ihre JMP RAX unvorhersehbar ist oder es zu unwahrscheinlich ist, dass die Anweisung nach ihr das Ziel des Sprungs sein wird; Intel empfiehlt, unmittelbar nach dem Sprung eine PAUSE oder UD2 zu setzen, um eine unnötige spekulative Ausführung zu verhindern. In diesem Fall würde die CPU stehenbleiben (nichts tun, bis sie das richtige Sprungziel findet).

Beachten Sie auch, dass Sie die MOV RAX, .. so verschieben sollten, dass sie so schnell wie möglich ausgeführt wird, so dass das Ziel des Sprungs so schnell wie möglich bekannt ist, so dass Sie die Zeit minimieren, die Sie gerade ausgeführt oder spekulativ ausgeführt haben Falsche Sache.

+0

statisch vorhergesagt nicht genommen macht keinen Sinn für eine unbedingte indirekte Verzweigung. IDK was passiert, wenn keine Verzweigungszielpuffervorhersage verfügbar ist, aber ich bezweifle, dass CPUs spekulativ die folgenden Befehle ausführen, unter der Annahme, dass das Verzweigungsziel der nächste Befehl ist. Obwohl ich vielleicht falsch liege, wenn "Pause" oder "ud2" empfohlen wird. Ich erinnere mich, dass ich gelesen habe, dass ich "ud2" verwende, um die spekulative Ausführung in einigen Fällen zu blockieren, aber ich habe vergessen, wo. –

+0

Alle modernen x86-CPUs, selbst Low-Power-Designs wie Atom, verfügen über eine gewisse Kapazität, um Verzweigungsziele für indirekte Zweige vorherzusagen. Größere Designs wie die SnB-Familie können sogar kurze Muster für indirekte Verzweigungszieladressen erkennen. –

+3

@PeterCordes: In den meisten Versionen des Intel Optimization Guide wird etwas wie (fast wörtlich aus "E.1 Rule 13" vom April 2012 Version) gesagt: "Wenn indirekte Zweige vorhanden sind, versuchen Sie, das wahrscheinlichste Ziel von eine indirekte Verzweigung, die unmittelbar auf die indirekte Verzweigung folgt.Alternativ, wenn indirekte Verzweigungen üblich sind, aber nicht vorhergesagt werden können, dann folge der indirekten Verzweigung mit einer UD2-Anweisung, was die Prozessordecodierung auf dem Durchfallweg stoppt ". Natürlich gibt es mehr Details in der Anleitung (und ich kondensierte, um die Kommentarbox Zeichen Grenze anzupassen) – Brendan