Wie die anderen Antworten alle angemessen vorgeschlagen haben, können Sie __builtin_expectdem 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 noinlineund 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