Branch auf?: operator?

8

Führt der Operator ? : für einen typischen modernen Compiler auf moderner Hardware zu einer Verzweigung, die sich auf die Befehlspipeline auswirkt?

Mit anderen Worten, was schneller ist, indem beide Fälle aufgerufen werden, um eine mögliche Verzweigung zu vermeiden:

%Vor%

oder wählen Sie das aus, das tatsächlich gelöscht werden soll und tun dies nur mit einem Operator ?: :

%Vor%

Mir ist klar, dass Sie keine Ahnung haben, wie lange purge () dauern wird, aber ich stelle nur eine allgemeine Frage darüber, ob ich jemals clean () zweimal aufrufen würde, um eine mögliche Verzweigung im Code zu vermeiden.

Ich verstehe, dass dies eine sehr kleine Optimierung ist und vielleicht keinen wirklichen Unterschied macht, aber ich würde es trotzdem gerne wissen. Ich erwarte, dass ?: nicht zu Verzweigungen führt, aber ich möchte sicherstellen, dass mein Verständnis korrekt ist.

    
WilliamKF 19.08.2011, 21:45
quelle

5 Antworten

5

Der Befehl CMOV (Conditional MOVe) ist seit dem Pentium Pro Bestandteil des x86-Befehlssatzes. Es wird selten automatisch von GCC aufgrund der häufig verwendeten Compiler-Optionen und Einschränkungen durch die C-Sprache generiert. Eine SETCC / CMOV-Sequenz kann durch Inline-Assemblierung in Ihrem C-Programm eingefügt werden. Dies sollte nur in Fällen geschehen, in denen die bedingte Variable ein zufällig oszillierender Wert in der inneren Schleife (Millionen von Ausführungen) eines Programms ist. In nicht oszillierenden Fällen und bei einfachen Schwingungsmustern können moderne Prozessoren Verzweigungen mit sehr hoher Genauigkeit vorhersagen. Im Jahr 2007 schlug Linus Torvalds hier vor, um den Einsatz von CMOV zu vermeiden in den meisten Situationen.

Intel beschreibt die bedingte Verschiebung im Intel® Architecture Software Developer's Manual, Volume 2: Instruction Set Referenzhandbuch :

%Vor%     
WilliamKF 22.08.2011, 19:11
quelle
5

Hängt von der Plattform ab. Insbesondere hängt es von der Größe der Sprungvorhersagetabelle der CPU ab und davon, ob die CPU bedingte Operationen erlaubt (wie bei ARM).

CPUs mit bedingten Operationen werden den zweiten Fall stark bevorzugen. CPUs mit größeren Sprungvorhersagetabellen bevorzugen den ersten Fall.

Die wirkliche Antwort (wie bei allen anderen Performance-Fragen): messen und vergleichen. Manchmal wirft der Rest des Codes einen Kurvenball und es ist normalerweise unmöglich, die Auswirkungen einiger Änderungen vorherzusagen.

    
Rom 19.08.2011 21:51
quelle
2

Ich kann mir nicht vorstellen, dass die erste Methode jemals schneller sein würde.

Mit der ersten Methode können Sie eine Verzweigung vermeiden, aber Sie ersetzen sie durch einen Funktionsaufruf, der normalerweise eine Verzweigung und viel mehr beinhaltet (es sei denn, es wurde inline). Selbst wenn inline, wenn die Funktionalität innerhalb der Purge () - Funktion absolut trivial wäre, wäre es fast sicher langsamer.

    
Eric Petroelje 19.08.2011 21:47
quelle
1

Das Aufrufen einer Funktion ist mindestens genauso teuer wie ein logischer Test + Sprung (und ja, der% ternäre Operator ? : würde einen Sprung erfordern).

    
Amber 19.08.2011 21:48
quelle
0

im ersten Fall Purge wird zweimal aufgerufen. Im zweiten Fall wird Purge einmal aufgerufen

Es ist schwierig, die Verzweigungsfrage zu beantworten, weil sie so sehr von Compilern und Befehlssätzen abhängig ist. Zum Beispiel auf einem ARM (der bedingte Befehlsausführung hat) kann es nicht verzweigen. Auf einem x86 wird es fast sicher

    
pm100 19.08.2011 21:49
quelle