Wie die anderen Antworten alle angemessen vorgeschlagen haben, können Sie __builtin_expect
dem Compiler einen Hinweis geben, wie der Assemblycode angeordnet werden soll. Wie die offiziellen Dokumente hervorheben , ist der in Ihr Gehirn eingebaute Assembler in den meisten Fällen nicht so gut wie der vom GCC-Team erstellte. Es ist immer am besten, tatsächliche Profildaten zu verwenden, um Ihren Code zu optimieren, anstatt zu raten.
In ähnlicher Weise, aber noch nicht erwähnt, ist eine GCC-spezifische Methode, um den Compiler zu zwingen, Code auf einem "kalten" Pfad zu generieren. Dies beinhaltet die Verwendung der Attribute noinline
und cold
, die genau das tun, wie sie klingen. Diese Attribute können nur auf Funktionen angewendet werden. Mit C ++ 11 können Sie jedoch Inline-Lambda-Funktionen deklarieren, und diese beiden Attribute können auch auf Lambda-Funktionen angewendet werden.
Obwohl dies immer noch in die allgemeine Kategorie einer Mikrooptimierung fällt und daher die Standardempfehlung gilt - Test nicht erraten -, halte ich es für allgemeiner nützlich als __builtin_expect
. Kaum eine Generation des x86-Prozessors verwendet Hinweise zur Verzweigungsvorhersage ( Referenz ). Das einzige, was Sie ohnehin beeinflussen können, ist die Reihenfolge des Assembler-Codes. Da Sie wissen, was Fehlerbehandlungs- oder "Edge-Case" -Code ist, können Sie diese Anmerkung verwenden, um sicherzustellen, dass der Compiler niemals einen Zweig dazu vorhersagt und ihn bei der Größenoptimierung vom "heißen" Code weg verknüpft.
Beispielnutzung:
void FooTheBar(void* pFoo)
{
if (pFoo == nullptr)
{
// Oh no! A null pointer is an error, but maybe this is a public-facing
// function, so we have to be prepared for anything. Yet, we don't want
// the error-handling code to fill up the instruction cache, so we will
// force it out-of-line and onto a "cold" path.
[&]() __attribute__((noinline,cold)) {
HandleError(...);
}();
}
// Do normal stuff
⋮
}
Noch besser ist, dass GCC dies automatisch zugunsten von Profil-Feedback ignoriert, wenn es verfügbar ist (z. B. beim Kompilieren mit -fprofile-use
).
Die offizielle Dokumentation finden Sie hier: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes