it-swarm.com.de

Warum ist eine bedingte Maßnahme nicht für einen Verzweigungsvorhersageschaden anfällig?

Nach dem Lesen von diesem Beitrag (Antwort auf StackOverflow) (im Abschnitt zur Optimierung) habe ich mich gefragt, warum bedingte Bewegungen für Branch Prediction Failure nicht anfällig sind. Ich habe auf einen Artikel über Kond-Verschiebungen hier (PDF von AMD) gefunden. Auch dort behaupten sie den Leistungsvorteil von cond. bewegt sich Aber warum ist das so? Ich sehe es nicht In dem Moment, in dem dieser ASM-Befehl ausgewertet wird, ist das Ergebnis des vorhergehenden CMP-Befehls noch nicht bekannt.

Vielen Dank.

69

Falsch vorhergesagte Branchen sind teuer

Ein moderner Prozessor führt im Allgemeinen zwischen einem und drei Befehlen pro Zyklus aus, wenn alles gut läuft (wenn er nicht auf Datenabhängigkeiten wartet, bis diese Befehle von vorherigen Befehlen oder aus dem Speicher ankommen).

Die obige Anweisung gilt überraschend gut für enge Schleifen, dies sollte Sie jedoch nicht vor einer zusätzlichen Abhängigkeit blenden, die die Ausführung einer Anweisung verhindern kann, wenn der Zyklus kommt: Damit eine Anweisung ausgeführt werden kann, muss der Prozessor gestartet sein Hol es ab und decodiere es 15-20 Zyklen vorher.

Was soll der Prozessor tun, wenn er auf eine Zweigstelle trifft? Das Abrufen und Dekodieren beider Ziele skaliert nicht (wenn mehrere Zweige folgen, müsste eine exponentielle Anzahl von Pfaden parallel abgerufen werden). Der Prozessor holt und dekodiert also nur spekulativ einen der beiden Zweige.

Deshalb sind falsch vorhergesagte Verzweigungen teuer: Sie kosten die 15-20 Zyklen, die aufgrund einer effizienten Befehlspipeline normalerweise unsichtbar sind.

Bedingter Umzug ist nie sehr teuer

Bedingte Verschiebungen erfordern keine Vorhersage, daher kann diese Strafe niemals eintreten. Es hat Datenabhängigkeiten, genau wie gewöhnliche Anweisungen. Tatsächlich hat eine bedingte Verschiebung mehr Datenabhängigkeiten als gewöhnliche Anweisungen, da die Datenabhängigkeiten sowohl die Fälle "Bedingung wahr" als auch "Bedingung falsch" enthalten. Nach einer Anweisung, die r1 bedingt zu r2 verschiebt, scheint der Inhalt von r2 sowohl vom vorherigen Wert von r2 als auch von r1 abzuhängen. Eine gut vorhergesagte bedingte Verzweigung ermöglicht es dem Prozessor, genauere Abhängigkeiten abzuleiten. Datenabhängigkeiten benötigen jedoch normalerweise ein bis zwei Zyklen, um anzukommen, wenn sie überhaupt Zeit brauchen.

Beachten Sie, dass ein bedingter Wechsel vom Speicher zum Register manchmal eine gefährliche Wette darstellt: Wenn der Zustand so ist, dass der aus dem Speicher gelesene Wert nicht dem Register zugewiesen wird, haben Sie auf nichts gewartet. Die in Befehlssätzen angebotenen bedingten Verschiebungsbefehle sind jedoch normalerweise zum Registrieren registriert, um diesen Fehler des Programmierers zu vermeiden.

61
Pascal Cuoq

Es geht um die Befehlspipeline . Denken Sie daran, dass moderne CPUs ihre Anweisungen in einer Pipeline ausführen, was zu einer erheblichen Leistungssteigerung führt, wenn der Ausführungsfluss von der CPU vorhersagbar ist.

cmov

    add     eax, ebx
    cmp     eax, 0x10
    cmovne  ebx, ecx
    add     eax, ecx

In dem Moment, in dem dieser ASM-Befehl ausgewertet wird, ist das Ergebnis des vorhergehenden CMP-Befehls noch nicht bekannt.

Vielleicht, aber die CPU weiß immer noch, dass die Anweisung, die der Variablen cmov folgt, unabhängig von dem Ergebnis der Anweisung cmp und cmov sofort ausgeführt wird. Der nächste Befehl kann somit sicher vorab abgerufen/decodiert werden, was bei Verzweigungen nicht der Fall ist.

Die nächste Anweisung kann sogar ausgeführt werden, bevor cmov ausgeführt wird (in meinem Beispiel wäre dies sicher)

ast

    add     eax, ebx
    cmp     eax, 0x10
    je      .skip
    mov     ebx, ecx
.skip:
    add     eax, ecx

In diesem Fall muss der Decoder der CPU, wenn er je .skip sieht, entscheiden, ob er mit dem Vorabrufen/Dekodieren der Anweisungen entweder 1) von der nächsten Anweisung oder 2) vom Sprungziel fortfahren soll. Die CPU wird vermuten, dass diese Vorwärtsbedingte Verzweigung nicht stattfindet, sodass der nächste Befehl mov ebx, ecx in die Pipeline eingeht.

Ein paar Zyklen später wird der je .skip ausgeführt und die Verzweigung genommen. Verdammt! Unsere Pipeline enthält jetzt einen zufälligen Müll, der niemals ausgeführt werden sollte. Die CPU muss alle zwischengespeicherten Anweisungen leeren und mit .skip: beginnen.

Dies ist die Leistungsverschlechterung von falsch vorhergesehenen Verzweigungen, was mit cmov niemals passieren kann, da der Ausführungsablauf dadurch nicht verändert wird.

42
Martin

Das Ergebnis ist zwar möglicherweise noch nicht bekannt, aber wenn andere Umstände (insbesondere die Abhängigkeitskette) dies zulassen, kann die CPU Anweisungen nach cmov neu ordnen und ausführen. Da es keine Verzweigung gibt, müssen diese Anweisungen auf jeden Fall ausgewertet werden.

Betrachten Sie dieses Beispiel:

cmoveq edx, eax
add ecx, ebx
mov eax, [ecx]

Die beiden Anweisungen, die auf cmov folgen, hängen nicht von dem Ergebnis von cmov ab. Sie können also ausgeführt werden, selbst wenn cmov selbst anhängig ist (dies wird als Out of Order-Ausführung bezeichnet). Auch wenn sie nicht ausgeführt werden können, können sie immer noch abgerufen und decodiert werden.

Eine verzweigte Version könnte sein:

    jne skip
    mov edx, eax
skip:
    add ecx, ebx
    mov eax, [ecx]

Das Problem hier ist, dass sich der Steuerungsfluss ändert und die CPU nicht schlau genug ist, um zu sehen, dass sie einfach die übersprungene mov-Anweisung "einfügen" könnte, wenn der Zweig als falsch angenommen wurde - stattdessen wird alles, was nach dem Zweig getan wurde, weggeworfen startet neu von vorne. Hier kommt die Strafe.

16
Jester

Sie sollten diese lesen. Suchen Sie mit Fog + Intel einfach nach CMOV.

Linus Torvalds Kritik an CMOV um 2007
Agner Fogs Vergleich von Mikroarchitekturen
Intel® 64- und IA-32-Architekturen - Referenzhandbuch

Kurze Antwort, korrekte Vorhersagen sind "frei", während die Vorhersage für bedingte Verzweigungen bei Haswell 14-20 Zyklen kosten kann. CMOV ist jedoch niemals kostenlos. Trotzdem denke ich, dass CMOV jetzt viel besser ist, als wenn Torvalds scherzte. Es gibt keinen richtigen für alle Zeiten, auf den alle Prozessoren antworten.

2
Olsonist

Ich habe diese Illustration aus der Folie von [Peter Puschner et al.], In der erklärt wird, wie sie in Einzelpfadcode umgewandelt wird und die Ausführung beschleunigt wird. 

 enter image description here

0
COLD ICE