2017-02-10 3 views
5

Von this Lesen kam ich über die nächsten zwei Zitate:Wie kann man die Verzweigungsvorhersage abbrechen?

Erstes Zitat:

Ein typischer Fall von unvorhersehbaren Verzweigungsverhalten ist, wenn das Vergleichsergebnis auf Daten abhängig ist.

Zweites Zitat:

Keine Branchen Keine Fehlvorhersagen Mittel

Für mein Projekt arbeite ich auf einem abhängigen Daten und ich führe viele if und switch Aussagen. Mein Projekt ist verwandt mit , also muss es so effizient wie möglich sein. Also wollte ich es anhand der vom Benutzer bereitgestellten Daten testen, um zu sehen, ob die Verzweigungsvorhersage mein Programm tatsächlich verlangsamt oder hilft. Ab dem Lesen here:

Fehlvorhersage Verzögerung liegt zwischen 10 und 20 Taktzyklen.

Was mich schockiert am meisten war:

die Zweige entfernen nicht nur die Laufzeitleistung des Codes verbessert, es hilft auch, den Compiler den Code zu optimieren.

Warum Verzweigungsvorhersage dann verwenden?

Gibt es eine Möglichkeit, den Compiler zu zwingen, Assemblercode ohne Verzweigungen zu generieren? oder um die Verzweigungsvorhersage zu deaktivieren, so dass CPU? also kann ich beide Ergebnisse vergleichen?

+2

Ihre Frage wird mit der Antwort auf die verknüpfte Frage beantwortet. –

+5

Beachten Sie, dass, wenn die CPU sie unterstützt, nicht jede Bedingung eine Verzweigung verursacht. Compiler sind ziemlich gut darin. Übrigens wird keine anständige CPU AFAIK Ihren Code im Falle von falschen Vorhersagen (messbar und im Durchschnitt!) Nicht verlangsamen, es wird es einfach nicht beschleunigen. Messen? Bereiten Sie einen Ad-hoc-Datensatz vor –

+0

@GeorgeStocker Danke! nutzte dies, um zu verstehen, was "Verzweigungsvorhersage" ist, aber unten nicht bemerkte, dass er einige nützliche Informationen lieferte. –

Antwort

8

zu sehen, ob die Verzweigungsvorhersage mein Programm tatsächlich verlangsamt oder

Verzweigungsvorhersage hilft keine Programme verlangsamen. Wenn die Leute über die Kosten verpasster Vorhersagen reden, reden sie darüber, wie viel teurer ein falsch vorhergesagter Zweig mit einem korrekt vorhergesagten Zweig verglichen wird.

Wenn die Verzweigungsvorhersage nicht existiert, wären alle Verzweigungen so teuer wie eine falsch vorhergesagte.

Also was "Fehlvorhersage Verzögerung ist zwischen 10 und 20 Uhr Zyklen" bedeutet wirklich, dass erfolgreiche Verzweigung Vorhersage 10 bis 20 Zyklen spart.

die Zweige entfernen nicht nur die Laufzeitleistung des Codes verbessert, es hilft auch, den Compiler den Code zu optimieren.

Warum Verzweigungsvorhersage dann verwenden?

Warum Verzweigungsprognose über das Entfernen von Verzweigungen verwenden? Du solltest nicht. Wenn ein Compiler Zweige entfernen kann, wird dies (vorausgesetzt, Optimierungen sind aktiviert), und wenn Programmierer Verzweigungen entfernen können (vorausgesetzt, dass dies die Lesbarkeit nicht beeinträchtigt oder es sich um einen performance-kritischen Code handelt), sollten sie dies tun.

Das macht die Verzweigungsvorhersage jedoch kaum nutzlos. Selbst wenn Sie so viele Zweige wie möglich aus einem Programm entfernen, enthält es immer noch viele, viele Zweige. Aus diesem Grund und aufgrund der Tatsache, wie teuer unvorhergesehene Zweige sind, ist eine Verzweigungsvorhersage für eine gute Leistung wesentlich.

Gibt es eine Möglichkeit, den Compiler zu zwingen, Assemblercode ohne Verzweigungen zu generieren?

Ein Optimierung der Compiler bereits Zweige von einem Programm entfernen, wenn es kann (ohne die Semantik des Programms zu ändern), aber, wenn wir über ein sehr einfaches int main() {return 0;} -Typs Programm sprechen, ist es unmöglich, alle zu entfernen Geäst. Schleifen erfordern Verzweigungen (es sei denn, sie werden ausgerollt, aber das funktioniert nur, wenn Sie die Anzahl der Iterationen im Voraus kennen). Dies gilt auch für die meisten if- und switch-Anweisungen. Wenn Sie die Anzahl der if s, switch und Loops in Ihrem Programm minimieren können, großartig, aber Sie werden nicht in der Lage sein, alle zu entfernen.

oder um die Verzweigungsvorhersage zu deaktivieren, so dass CPU? also kann ich beide Ergebnisse vergleichen?

Nach meinem besten Wissen ist es unmöglich, Verzweigung Vorhersage auf x86 oder x86-64 CPUs zu deaktivieren. Und wie gesagt, dies würde niemals die Leistung verbessern (obwohl es es vorhersehbar machen könnte, aber das ist normalerweise nicht erforderlich in den Kontexten, in denen diese CPUs verwendet werden).

+0

In einigen Fällen kann eine kleine, aber variable Zählschleife profitabel voll sein (max count) und mit Prädikation/bedingter Bewegung "maskiert" die Effekte der nicht benötigten Berechnung ausgerollt werden. –

+0

Danke für die Antwort. Spült die Pipeline frei? Wenn eine falsche Vorhersage dann ist es herausgezogen worden. Ich verstehe den Gewinn im Falle eines Treffers. Aber wenn die CPU versagt, bedeutet das nicht, dass wir noch einen Zyklus bezahlen, um die Pipeline zu spülen? –

+1

@TonyTannous Das hängt von der genauen CPU-Architektur ab (wie es die meisten Dinge sind, über die wir hier reden), aber ich verstehe, dass es bei modernen CPUs keine Wartezeiten beim Spülen der Pipeline gibt. Eine schnelle Google-Suche führt dazu (http://www.realworldtech.com/sandy-bridge/3/), was dies zu bestätigen scheint ("Sobald eine Verzweigungsfehlvorhersage entdeckt wird, kann der Kern die Decodierung neu starten sobald der korrekte Pfad bekannt ist, gleichzeitig, dass die Out-of-Order-Maschine Ups aus dem falsch spekulierten Pfad entfernt. ... – sepp2k

5

Moderne Prozessoren haben Pipelines, die es der CPU ermöglichen, viel schneller zu arbeiten, als es sonst möglich wäre. Dies ist eine Form der Parallelität, bei der es beginnt, einen Befehl einige Taktzyklen zu verarbeiten, bevor der Befehl tatsächlich benötigt wird. Sehen Sie hier here für weitere Details.

Das funktioniert gut, bis wir einen Zweig treffen. Da wir springen, ist die Arbeit in der Pipeline nicht mehr relevant. Die CPU muss dann die Pipeline leeren und neu starten. Dies verursacht eine Verzögerung von einigen Taktzyklen, bis die Pipeline wieder voll ist. Dies wird als Pipeline-Stall bezeichnet.

Moderne CPUs sind clever genug, wenn es um unbedingte Sprünge geht, um dem Sprung beim Befüllen der Pipeline zu folgen und so den Strömungsabriss zu verhindern. Dies funktioniert nicht, wenn es um Verzweigungen geht, da die CPU nicht genau weiß, wohin der Sprung gehen wird.

Die Verzweigungsvorhersage versucht, dieses Problem zu lösen, indem eine Schätzung vorgenommen wird, welchem ​​Zweig die CPU folgen wird, bevor der Sprung vollständig ausgewertet wird. Dies (wenn es funktioniert) verhindert den Stall.

Da fast alle Programmierungen Entscheidungen treffen, ist eine Verzweigung unvermeidbar. Aber man kann sicherlich Code mit weniger Verzweigungen schreiben und so die durch Fehleinschätzungen verursachten Verzögerungen verringern. Sobald wir verzweigen, erlaubt uns die Verzweigungsvorhersage zumindest, die Dinge richtig zu machen und keinen CPU-Pipeline-Stillstand zu haben.

+2

Ein kleiner Nitpick: sogar unbedingte Sprünge können problematisch sein, da sie variabel sein können (denken Sie an MIPS 'jar') oder indirekt (z. B. x86' jmp [rbx] '). –

Verwandte Themen