Ich habe die beliebte Antwort zu Branch Prediction von https://stackoverflow.com/q/11227809/555690 gelesen und etwas verwirrt mich:
- Wenn Sie richtig geraten haben, geht es weiter.
- Wenn Sie falsch geraten haben, stoppt der Kapitän, macht einen Rückzieher und schreit Sie an, den Schalter zu betätigen. Dann kann es den anderen Pfad neu starten.
Wenn Sie jedes Mal richtig raten, wird der Zug niemals anhalten müssen.
Wenn Sie zu oft falsch raten, verbringt der Zug viel Zeit damit, anzuhalten, zu sichern und neu zu starten.
Aber das ist, was ich nicht verstehe: Um zu wissen, ob Ihre Vermutung richtig oder falsch war, müssen Sie trotzdem eine Zustandsüberprüfung durchführen . Wie funktioniert die Verzweigungsvorhersage überhaupt, wenn Sie in beiden Fällen immer noch dieselbe bedingte Prüfung durchführen?
Was ich damit sagen will, ist, ist die Verzweigungsvorhersage nicht genau das Gleiche wie die Verzweigungsvorhersage, weil Sie sowieso die gleichen bedingten Prüfungen durchführen? (offensichtlich irre ich mich, aber ich verstehe es nicht)
quelle
Antworten:
Natürlich wird der Zustand jedes Mal überprüft. Aber bis es überprüft wird, ist es weit oben in der CPU-Pipeline. In der Zwischenzeit sind weitere Anweisungen in die Pipeline eingegangen und befinden sich in verschiedenen Phasen der Ausführung.
Normalerweise folgt unmittelbar auf eine Bedingung eine bedingte Verzweigungsanweisung, die entweder verzweigt, wenn die Bedingung WAHR ergibt, oder durchfällt, wenn die Bedingung FALSCH ergibt. Dies bedeutet, dass nach dem Bedingungsbefehl und dem Verzweigungsbefehl zwei verschiedene Befehlsströme in die Pipeline geladen werden können, je nachdem, ob die Bedingung TRUE oder FALSE ergibt. Unglücklicherweise weiß die CPU unmittelbar nach dem Laden der Bedingungsanweisung und der Verzweigungsanweisung noch nicht, wie die Bedingung ausgewertet wird, muss jedoch weiterhin Daten in die Pipeline laden. Es wird also eine der beiden Anweisungen ausgewählt, basierend auf einer Vermutung, wie die Bedingung ausgewertet wird.
Später, wenn der Bedingungsbefehl die Pipeline hinaufläuft, ist es an der Zeit, ihn auszuwerten. Zu diesem Zeitpunkt findet die CPU heraus, ob ihre Vermutung richtig oder falsch war.
Wenn sich herausstellt, dass die Vermutung richtig ist, wurde der Zweig an die richtige Stelle verschoben, und die richtigen Anweisungen wurden in die Pipeline geladen. Wenn sich herausstellt, dass die Vermutung falsch war, dann müssen alle Befehle, die nach dem bedingten Verzweigungsbefehl in die Pipeline geladen wurden, verworfen werden, und das Abrufen von Befehlen muss erneut an der richtigen Stelle beginnen.
Änderung
Als Antwort auf den Kommentar von StarWeaver, um eine Vorstellung davon zu bekommen, was die CPU tun muss, um einen einzelnen Befehl auszuführen:
Betrachten Sie etwas so Einfaches, wie
MOV AX,[SI+10]
wir Menschen es naiv als "AX mit dem Wort bei SI plus 10 laden" betrachten. Grob gesagt muss die CPU:Das sind satte 10 Schritte. Einige dieser Schritte werden auch bei nicht über Pipelines verbundenen CPUs wegoptimiert, zum Beispiel erhöht die CPU den PC fast immer parallel zum nächsten Schritt, was eine einfache Sache ist, da der PC ein sehr, sehr spezielles Register ist Nie für einen anderen Job verwendet, daher besteht zwischen verschiedenen Teilen der CPU keine Möglichkeit eines Konflikts um den Zugriff auf dieses bestimmte Register. Dennoch bleiben uns 8 Schritte für eine so einfache Anweisung, und ich nehme an, dass ich bereits ein gewisses Maß an Raffinesse für die CPU voraussetze, zum Beispiel gehe ich davon aus, dass für die keine zusätzlichen Schritte erforderlich sind Addierer, um die Addition tatsächlich durchzuführen, bevor das Ergebnis daraus abgelesen werden kann,
Bedenken Sie nun, dass es kompliziertere Adressierungsmodi wie
MOV AX, [DX+SI*4+10]
und sogar weitaus kompliziertere Befehle gibt,MUL AX, operand
die tatsächlich Schleifen in der CPU ausführen, um deren Ergebnis zu berechnen.Mein Punkt hier ist also, dass die Metapher "atomarer Ebene" bei weitem nicht für die CPU-Befehlsebene geeignet ist. Es ist möglicherweise für die Pipeline-Step-Ebene geeignet, wenn Sie nicht zu weit auf die eigentliche Logik-Gate-Ebene heruntergehen möchten.
quelle
MOV AX,[SI+10]
fremd, nicht "einfach". Die meisten Programmierer haben heute noch nie Assembler geschrieben. Wir denken nicht "naiv" daran, dass es irgendetwas bedeutet.Stellen Sie es sich wie einen Ausflug ohne GPS vor. Sie kommen zu einer Kreuzung und denken, Sie müssen abbiegen, sind sich aber nicht ganz sicher. Sie biegen also ab, bitten aber Ihren Beifahrer, die Karte zu überprüfen. Vielleicht sind Sie drei Meilen die Straße hinunter, wenn Sie fertig sind mit Streiten darüber, wo Sie sind. Wenn Sie recht gehabt hätten, wären Sie drei Meilen weiter als wenn Sie angehalten und gestritten hätten, bevor Sie umgedreht wären. Wenn Sie sich geirrt haben, müssen Sie sich umdrehen.
CPU-Pipelines funktionieren genauso. Bis sie den Zustand überprüfen können, sind sie schon ein Stück weiter. Der Unterschied ist, dass sie die drei Meilen nicht zurück fahren müssen, sondern nur den Vorsprung verlieren. Das heißt, es schadet nicht, es zu versuchen.
quelle
Nach meinem Verständnis ist die Verzweigungsvorhersage am nützlichsten, wenn die zu überprüfende Bedingung das Ergebnis von etwas erfordert, das teuer ist oder noch in Bearbeitung ist, und Sie andernfalls Ihre Daumen drehen und auf den Wert warten, um die Bedingung zu bewerten.
Bei der Ausführung außerhalb der Reihenfolge können Sie die Verzweigungsvorhersage verwenden, um leere Stellen in der Pipeline auszufüllen, die die CPU sonst nicht verwenden könnte. In einer Situation, in der aus irgendeinem Grund keine Leerlaufzyklen in der Pipeline vorhanden sind, gibt es keine Verbesserung der Verzweigungsvorhersage.
Der Schlüssel hierbei ist jedoch, dass die CPU die Arbeit für einen der vorhergesagten Zweige startet, da sie den Zustand selbst noch nicht auswerten kann.
quelle
Kurzform:
Einige CPUs können mit der Bearbeitung eines neuen Befehls beginnen, bevor der alte abgeschlossen ist. Dies sind die CPUs, die die Verzweigungsvorhersage verwenden.
Ein Pseudocode-Beispiel:
Der obige Code prüft eine Bedingung und basierend auf dem Ergebnis muss er entweder den am Speicherort
addThis
gespeicherten Wert oder den am Speicherort gespeicherten Wert zurückgebenreadThat
. Wenn die Verzweigungsvorhersage den Zustand vorhersagttrue
, liest die CPU bereits den an der Speicherstelle gespeicherten Wert,addThis
während sie die zur Auswertung derif
Anweisung erforderliche Berechnung vornimmt. Dies ist ein vereinfachtes Beispiel.quelle
Ja, der Zustand wird so oder so geprüft. Der Vorteil der Verzweigungsvorhersage besteht jedoch darin, dass Sie arbeiten können, anstatt auf das Ergebnis der Bedingungsprüfung zu warten.
Nehmen wir an, Sie müssen einen Aufsatz schreiben und es kann sich um Thema A oder Thema B handeln. Sie wissen aus früheren Aufsätzen, dass Ihr Lehrer Thema A besser mag als B und wählt es häufiger aus. Anstatt auf seine Entscheidung zu warten, können Sie den Aufsatz über das erste Thema schreiben. Nun gibt es zwei mögliche Ergebnisse:
Moderne CPUs laufen die meiste Zeit im Leerlauf, weil sie auf E / A-Antworten oder das Ergebnis anderer Berechnungen warten. Diese Zeit kann für zukünftige Arbeiten genutzt werden.
Selbst wenn Sie das, was Sie in dieser Leerlaufzeit tun, verwerfen müssen, ist es am effektivsten, wenn Sie den vom Programm gewählten Pfad erraten können. Und moderne CPUs haben diese Fähigkeit.
quelle