it-swarm.com.de

Wie funktioniert die Verzweigungsvorhersage, wenn Sie noch nach den Bedingungen suchen müssen?

Ich habe die beliebte Antwort zu Branch Prediction von https://stackoverflow.com/q/11227809/55569 gelesen und es gibt etwas, das mich verwirrt:

  • Wenn Sie richtig geraten haben, geht es weiter.
  • Wenn Sie falsch geraten haben, hält der Kapitän an, fährt zurück und schreit Sie an, um den Schalter umzulegen. Dann kann es auf dem anderen Pfad neu starten.

Wenn Sie jedes Mal richtig raten, muss der Zug niemals anhalten.

Wenn Sie zu oft falsch raten , verbringt der Zug viel Zeit damit, anzuhalten, zu sichern und neu zu starten.

Aber das ist es, was ich nicht verstehe: um zu wissen , ob Ihre Vermutung richtig oder falsch war, müssen Sie Machen Sie eine Bedingungsprüfung sowieso. Wie funktioniert die Verzweigungsvorhersage überhaupt, wenn Sie in beiden Fällen immer noch dieselbe bedingte Prüfung durchführen?

Ich versuche zu sagen, ist die Verzweigungsvorhersage nicht genau das Gleiche wie die Verzweigungsvorhersage, weil Sie sowieso die gleichen bedingten Überprüfungen durchführen? (Natürlich irre ich mich, aber ich verstehe es nicht)

33
Omega

Natürlich wird der Zustand jedes Mal überprüft. Aber wenn es überprüft wird, ist es weit oben in der CPU-Pipeline. In der Zwischenzeit sind auch andere Anweisungen in die Pipeline eingetreten und befinden sich in verschiedenen Ausführungsphasen.

Normalerweise folgt auf eine Bedingung sofort ein bedingter Verzweigungsbefehl, der entweder verzweigt, wenn die Bedingung TRUE ergibt, oder durchfällt, wenn die Bedingung FALSE ergibt. Dies bedeutet, dass es zwei verschiedene Befehlsströme gibt, die nach dem Bedingungsbefehl und dem Verzweigungsbefehl in die Pipeline geladen werden können, je nachdem, ob die Bedingung TRUE oder FALSE ergibt. Leider weiß die CPU unmittelbar nach dem Laden des Bedingungsbefehls und des Verzweigungsbefehls noch nicht, wie der Zustand ausgewertet wird, muss jedoch weiterhin Daten in die Pipeline laden. Es wählt also einen der beiden Befehlssätze aus, basierend auf einer Vermutung, wie die Bedingung bewertet 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, ging der Zweig an die richtige Stelle und die richtigen Anweisungen wurden in die Pipeline geladen. Wenn sich herausstellt, dass die Vermutung falsch war, waren alle Anweisungen, die nach der bedingten Verzweigungsanweisung in die Pipeline geladen wurden, falsch. Sie müssen verworfen werden, und das Abrufen der Anweisungen muss erneut an der richtigen Stelle beginnen.

Änderung

Als Antwort auf den Kommentar von StarWeaver, um eine Vorstellung davon zu geben, was die CPU tun muss, um eine einzelne Anweisung auszuführen:

Betrachten Sie etwas so Einfaches wie MOV AX,[SI+10] was wir Menschen naiv als "AX mit dem Wort bei SI plus 10 laden" betrachten. Die CPU muss ungefähr:

  1. den Inhalt des PCs (das "Programmzählerregister") an den Adressbus senden;
  2. lesen Sie den Befehls-Opcode vom Datenbus.
  3. pC inkrementieren;
  4. dekodieren Sie den Opcode, um herauszufinden, was damit zu tun ist.
  5. den Inhalt des PCs an den Adressbus senden;
  6. lesen Sie den Befehlsoperanden (in diesem Fall 10) vom Datenbus.
  7. pC inkrementieren;
  8. zuführen des Operanden und des SI zum Addierer;
  9. das Ergebnis des Addierers an den Adressbus senden;
  10. lesen Sie AX vom Datenbus.

Dies sind satte 10 Schritte. Einige dieser Schritte werden auch bei CPUs ohne Pipeline optimiert. Beispielsweise erhöht die CPU den PC fast immer parallel zum nächsten Schritt. Dies ist einfach, da der PC ein sehr, sehr spezielles Register ist Wird nie für einen anderen Job verwendet, daher besteht keine Möglichkeit eines Konflikts zwischen verschiedenen Teilen der CPU um den Zugriff auf dieses bestimmte Register. Wir haben jedoch noch 8 Schritte für eine so einfache Anweisung übrig und stellen fest, dass ich im Namen der CPU bereits von einem gewissen Grad an Raffinesse ausgehe, zum Beispiel davon aus, dass für die CPU kein ganzer zusätzlicher Schritt erforderlich ist Addierer, um die Addition tatsächlich durchzuführen, bevor das Ergebnis daraus gelesen werden kann, und ich gehe davon aus, dass die Ausgabe des Addierers direkt an den Adressbus gesendet werden kann, ohne in einem internen Zwischenadressierungsregister gespeichert werden zu müssen.

Bedenken Sie nun, dass es kompliziertere Adressierungsmodi gibt, wie MOV AX, [DX+SI*4+10] und noch viel kompliziertere Anweisungen wie MUL AX, operand die tatsächlich Schleifen innerhalb der CPU ausführen, um ihr Ergebnis zu berechnen.

Mein Punkt hier ist also, dass die Metapher "atomare Ebene" für die CPU-Befehlsebene bei weitem nicht geeignet ist. Es ist möglicherweise für die Pipeline-Stufenebene geeignet, wenn Sie nicht zu weit bis zur tatsächlichen Logikgatterebene gehen möchten.

19
Mike Nakis

Stellen Sie sich das wie einen Roadtrip ohne GPS vor. Sie kommen an eine Kreuzung und denken, Sie müssen abbiegen, sind sich aber nicht ganz sicher. Sie biegen also ab, bitten aber Ihren Passagier, die Karte zu überprüfen. Vielleicht sind Sie drei Meilen die Straße hinunter, wenn Sie mit dem Streiten darüber fertig sind, wo Sie sich befinden. Wenn Sie Recht hätten, wären Sie drei Meilen weiter als wenn Sie vor dem Abbiegen angehalten und gestritten hätten. 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 nicht die drei Meilen zurückfahren müssen, sondern nur den Vorsprung verlieren. Das heißt, es schadet nicht, es zu versuchen.

31
Karl Bielefeldt

Nach meinem Verständnis ist die Verzweigungsvorhersage am nützlichsten, wenn die Bedingung, die Sie überprüfen müssen, das Ergebnis von etwas erfordert, das teuer ist oder noch in Bearbeitung ist, und Sie ansonsten mit den Daumen drehen und darauf warten, dass der Wert die Bedingung bewertet.

Mit Dingen wie 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 keinen Gewinn bei der Verzweigungsvorhersage.

Der Schlüssel hier ist jedoch, dass die CPU die Arbeit für einen der vorhergesagten Zweige startet, weil sie nicht die Bedingung selbst noch auswerten kann.

2
Dogs

Kurzform:

Einige CPUs können mit der Arbeit an einem neuen Befehl beginnen, bevor sie den alten beenden. Dies sind die CPUs, die die Verzweigungsvorhersage verwenden.

Ein Pseudocode-Beispiel:

int globalVariable;
int Read(int* readThis, int* readThat)
{
    if ((globalVariable*globalVariable % 17) < 5)
       return *readThis;
    else
       return *readThat;
}

Der obige Code überprüft eine Bedingung und gibt basierend auf dem Ergebnis entweder den am Speicherort addThis gespeicherten Wert oder den unter readThat gespeicherten Wert zurück. Wenn die Verzweigungsvorhersage voraussagt, dass die Bedingung true ist, liest die CPU bereits den am Speicherort addThis gespeicherten Wert, während sie die zur Auswertung der Anweisung if erforderliche Berechnung durchführt. Dies ist ein vereinfachtes Beispiel.

1
Peter

Ja, der Zustand wird so oder so überprü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:

  1. Sie haben Ihren Aufsatz zum falschen Thema begonnen und müssen das, was Sie bisher geschrieben haben, fallen lassen. Sie müssen anfangen, über das andere Thema zu schreiben, und es ist der gleiche Zeitaufwand, als hätten Sie gewartet.
  2. Sie haben richtig geraten und bereits gearbeitet.

Moderne CPUs sind die meiste Zeit im Leerlauf, weil sie auf IO Antworten oder das Ergebnis anderer Berechnungen) warten. Diese Zeit kann für zukünftige Arbeiten verwendet werden.

Selbst wenn Sie ablehnen müssen, was Sie in dieser Leerlaufzeit tun, ist es höchstwahrscheinlich effektiver, wenn Sie erraten können, welchen Pfad das Programm wählen wird. Und moderne CPUs haben diese Fähigkeit.

1
Otomo