Was ist der zwischen wahrscheinlichen und unwahrscheinlichen Aufrufen im Kernel? Beim Durchsuchen der Kernelquelle habe ich diese Aussagen gefunden.
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
Könnte jemand etwas Licht ins Dunkel bringen?
Antworten:
Sie sind Compiler-Hinweise für GCC. Sie werden in Bedingungen verwendet, um dem Compiler mitzuteilen, ob ein Zweig wahrscheinlich genommen wird oder nicht. Dies kann dem Compiler helfen, den Code so festzulegen, dass er für das häufigste Ergebnis optimal ist.
Sie werden wie folgt verwendet:
Es sollte mit großer Sorgfalt verwendet werden (dh basierend auf den tatsächlichen Ergebnissen der Branchenprofilierung). Ein falscher Hinweis kann die Leistung (offensichtlich) beeinträchtigen.
Einige Beispiele, wie der Code optimiert werden kann, können leicht durch Suchen gefunden werden
GCC __builtin_expect
. Dieser Blog-Beitrag gcc-Optimierung: __builtin_expect beschreibt beispielsweise eine Demontage damit.Die Art der Optimierungen, die durchgeführt werden können, ist sehr prozessorspezifisch. Die allgemeine Idee ist, dass Prozessoren Code häufig schneller ausführen, wenn er nicht überall verzweigt / springt. Je linearer es ist und je vorhersehbarer die Zweige sind, desto schneller läuft es. (Dies gilt insbesondere für Prozessoren mit tiefen Pipelines.)
Der Compiler gibt den Code also so aus, dass der wahrscheinlichste Zweig keinen Sprung beinhaltet, wenn dies beispielsweise die Ziel-CPU bevorzugt.
quelle
Lassen Sie uns dekompilieren, um zu sehen, was GCC 4.8 damit macht
Ohne zu erwarten
Kompilieren und dekompilieren Sie mit GCC 4.8.2 x86_64 Linux:
Ausgabe:
Die Befehlsreihenfolge im Speicher blieb unverändert: zuerst die
printf
und dannputs
und dieretq
Rückgabe.Mit erwarten
Ersetzen Sie nun durch
if (i)
:und wir bekommen:
Das
printf
(kompiliert nach__printf_chk
) wurde nachputs
und nach der Rückkehr an das Ende der Funktion verschoben, um die Verzweigungsvorhersage zu verbessern, wie in anderen Antworten erwähnt.Es ist also im Grunde dasselbe wie:
Diese Optimierung wurde nicht durchgeführt
-O0
.Aber viel Glück beim Schreiben eines Beispiels, das mit und
__builtin_expect
ohne schneller läuft. CPUs sind heutzutage wirklich schlau . Meine naiven Versuche sind hier .C ++ 20
[[likely]]
und[[unlikely]]
C ++ 20 hat diese C ++ - Integrationen standardisiert: /programming/51797959/how-to-use-c20s-likely-unlikely-attribute-in-if-else-statement Sie werden wahrscheinlich (a Wortspiel!) das Gleiche tun.
quelle