Come le altre risposte hanno tutte adeguatamente suggerito, puoi usare __builtin_expect
per dare al compilatore un suggerimento su come organizzare il codice dell'assembly. Come sottolineano i documenti ufficiali , nella maggior parte dei casi, l'assemblatore integrato nel tuo cervello non sarà buono come quello creato dal team di GCC. È sempre meglio utilizzare i dati del profilo effettivo per ottimizzare il codice, piuttosto che indovinare.
Lungo linee simili, ma non ancora menzionate, è un modo specifico di GCC per forzare il compilatore a generare codice su un percorso "freddo". Ciò implica l'uso degli attributi noinline
e cold
, che fanno esattamente quello che suonano come fanno. Questi attributi possono essere applicati solo alle funzioni, ma con C ++ 11 è possibile dichiarare funzioni lambda inline e questi due attributi possono essere applicati anche alle funzioni lambda.
Anche se questo rientra ancora nella categoria generale di una microottimizzazione, e quindi si applica il consiglio standard - test non indovinare - penso che sia più generalmente utile di __builtin_expect
. Quasi nessuna generazione del processore x86 utilizza i suggerimenti di previsione dei rami ( riferimento ), quindi l'unica cosa che sarai in grado di influenzare comunque è l'ordine del codice assembly. Dato che sai cos'è il codice di gestione degli errori o "caso limite", puoi usare questa annotazione per assicurarti che il compilatore non preveda mai un ramo ad esso e lo colleghi lontano dal codice "caldo" durante l'ottimizzazione per le dimensioni.
Utilizzo del campione:
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
⋮
}
Ancora meglio, GCC lo ignorerà automaticamente a favore del feedback del profilo quando è disponibile (ad esempio, durante la compilazione con -fprofile-use
).
Consulta la documentazione ufficiale qui: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes