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:
- den Inhalt des PCs (das "Programmzählerregister") an den Adressbus senden;
- Lesen des Befehls-Opcodes vom Datenbus;
- Inkrement PC;
- Dekodiere den Opcode, um herauszufinden, was damit zu tun ist.
- den Inhalt des PCs an den Adressbus senden;
- Lese den Befehlsoperanden (in diesem Fall 10) vom Datenbus;
- Inkrement PC;
- führe den Operanden und SI dem Addierer zu;
- das Ergebnis des Addierers an den Adressbus ausgeben;
- Lesen Sie AX aus dem Datenbus.
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.