Con frecuencia, las macros conocidas como likelyy unlikelyayudan al compilador a saber si ifgeneralmente se va a ingresar o omitir un Usarlo da como resultado algunas mejoras de rendimiento (más bien menores).
Empecé a usarlos recientemente, y no estoy seguro de con qué frecuencia se deben usar esas sugerencias. Actualmente lo uso con comprobación de errores ifs, que generalmente están marcados como unlikely. Por ejemplo:
mem = malloc(size);
if (unlikely(mem == NULL))
goto exit_no_mem;
Parece correcto, pero la comprobación de errores ifocurre con bastante frecuencia y, en consecuencia, el uso de dichas macros.
Mi pregunta es, ¿es demasiado tener likelyy unlikelymacros en cada comprobación de errores if?
Mientras estamos en eso, ¿qué otros lugares se usan a menudo?
En mi uso actual, está en una biblioteca que hace una abstracción del subsistema en tiempo real, por lo que los programas serían portátiles entre RTAI, QNX y otros. Dicho esto, la mayoría de las funciones son bastante pequeñas y llaman directamente a una o dos funciones más. Muchos son incluso static inlinefunciones.
Entonces, antes que nada, no es una aplicación que pueda perfilar. No tiene sentido "identificar cuellos de botella" ya que es una biblioteca, no una aplicación independiente.
En segundo lugar, es algo así como "Sé que esto es poco probable, también podría decírselo al compilador". No trato activamente de optimizar el if.
fuente

likelyyunlikelyexiste y lo que hacen. No encontré nada que sugiriera cuándo y dónde es mejor usarlos.Respuestas:
¿Necesita tanto rendimiento que está dispuesto a contaminar su código con eso? Es una optimización menor.
A menos que pueda responder
yesa todo lo anterior, no se moleste con cosas como esta.Editar: en respuesta a la edición. Incluso cuando no puede crear un perfil, generalmente puede estimar puntos de acceso. Una función de asignación de memoria llamada por todos es un buen candidato, especialmente porque requiere un solo uso de la macro para funcionar en toda la biblioteca.
fuente
(un)likelymacro rara vez se usa y solo en código extremadamente crítico para el rendimiento? ¿Es una "mala práctica" usarlo con frecuencia, o simplemente "innecesario"?if (likely(x==2 || x==3)) doOneThing(); else switch(x) { ... }, podría juzgar que el uso del programador de unifpara los valores 2 y 3 no fue simplemente una consecuencia de que el programador no supiera que C puede asociar doscaseetiquetas con un solo controlador.Si está escribiendo para x86 / x64 (y no está utilizando CPU de 20 años), la ganancia de rendimiento al usar __builtin_expect () será insignificante, si es que la hay. La razón es que las CPU modernas x86 / x64 (aunque no estoy 100% seguro sobre Atom), tienen una predicción dinámica de rama, por lo que esencialmente la CPU "aprende" sobre la rama que se toma con más frecuencia. Claro, esta información puede almacenarse solo para un número limitado de sucursales, sin embargo, solo hay dos casos posibles. Si (a) es una rama "de uso frecuente", entonces su programa se beneficiará de esa predicción de rama dinámica, y si (b) es una rama "rara", realmente no verá ningún impacto realista en el rendimiento debido a predicciones erróneas en tales ramas raras (20 ciclos de CPU de predicción errónea de ramas no son MUY malo si sucede una vez en una luna azul).
NB: esto NO implica que en la x86 / x64 moderna la importancia de la predicción errónea de la rama sea menor: cualquier rama con 50-50 de probabilidad de saltar-nojump aún incurrirá en una penalización (IIRC 10-20 ciclos de CPU), por lo que en las ramas del bucle interno puede Todavía hay que evitarlo. Solo es importante que __builtin_expect () en x86 / x64 haya disminuido (IIRC, hace unos 10-15 años más o menos), principalmente debido a la predicción dinámica de las ramas.
NB2: para otras plataformas más allá de x86 / x64, YMMV.
fuente
unlikelynotación.