Como las otras respuestas han sugerido adecuadamente, puede usar __builtin_expect
para darle al compilador una pista sobre cómo organizar el código ensamblador. Como señalan los documentos oficiales , en la mayoría de los casos, el ensamblador integrado en su cerebro no será tan bueno como el creado por el equipo de GCC. Siempre es mejor usar datos de perfil reales para optimizar su código, en lugar de adivinar.
En líneas similares, pero aún no mencionadas, hay una forma específica de GCC para forzar al compilador a generar código en una ruta "fría". Esto implica el uso de los atributos noinline
y cold
, que hacen exactamente lo que parecen. Estos atributos solo se pueden aplicar a funciones, pero con C ++ 11, puede declarar funciones lambda en línea y estos dos atributos también se pueden aplicar a funciones lambda.
Aunque esto todavía cae en la categoría general de una microoptimización y, por lo tanto, se aplica el consejo estándar (prueba, no adivines), creo que es más útil en general que __builtin_expect
. Casi ninguna generación del procesador x86 usa sugerencias de predicción de rama ( referencia ), por lo que lo único que podrá afectar de todos modos es el orden del código ensamblador. Ya que sabe lo que es el código de manejo de errores o "caso de borde", puede usar esta anotación para asegurarse de que el compilador nunca predecirá una rama y lo vinculará fuera del código "caliente" al optimizar el tamaño.
Uso de muestra:
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
⋮
}
Aún mejor, GCC automáticamente ignorará esto a favor de la retroalimentación del perfil cuando esté disponible (por ejemplo, al compilar con -fprofile-use
).
Consulte la documentación oficial aquí: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes