Un ingeniero de Intel realizó un cambio de una línea en el conjunto de compiladores GCC, aumentando el peso de la predicción incorrecta de bifurcación en procesadores x86. Este cambio permitió mejorar el rendimiento del código generado en la prueba 544.nab_r en un 12.7% al activar las optimizaciones «-O2 -mtune=graniterapids» para CPU Intel Granite Rapids/Xeon 6 y en un 12.1% al activar las optimizaciones «-O2 -mtune=znver5» en CPU AMD Zen5.
El cambio de peso de «COSTS_N_INSNS (2)» a «COSTS_N_INSNS (2) + 3» aumenta la importancia del error de predicción de 2 a 5 instrucciones condicionales, lo que refleja mejor las particularidades de los pipelines de procesamiento de instrucciones en los CPUs modernos, donde los errores de predicción de bifurcación son más costosos. El cambio de peso lleva a que el compilador fuerce la transformación de expresiones «if» en instrucciones condicionales sin saltos, como CMOV, que eliminan las pausas causadas por incorrectas predicciones de bifurcación, derivadas de la necesidad de reiniciar el estado del pipeline. Anteriormente, el peso «COSTS_N_INSNS (2) + 3» se especificaba en GCC solo para los procesadores Intel Ice Lake y Alder Lake, y ahora se aplica al perfil general (generic) de procesadores x86.
Es notable que tras la aceptación del parche, surgió una regresión, causando que la prueba «Hint» se ejecutara un 30% más lentamente para uno de los desarrolladores de GCC al compilar con las opciones «-march=generic -mtune=znver5» y «-march=generic -mtune=graniterapids». El rendimiento en las pruebas SPEC2017 y SPEC2026 después del cambio se mantuvo al mismo nivel. La existencia de la regresión ha sido confirmada por el autor del commit original, quien reporta que la disminución en el tiempo de ejecución de la prueba Hint es del 14% al compilar con las opciones «-O2 -mtune=generic -march=x86-64-v3».
La desaceleración se explica porque en el código de la prueba Hint solo hay una construcción condicional, que GCC transforma en una representación basada en CMOV. Esta construcción se ejecuta con poca frecuencia (en un 3%) y su optimización no afecta el rendimiento. Sin embargo, el cambio en el modo de generación de código condujo a un efecto colateral, ralentizando la ejecución de un código que se ejecuta con más frecuencia.
Fuente: opennet.ru
