linux - safe - ¿Cuál es la diferencia entre los niveles de optimización de gcc?
gentoo skylake (4)
Encontré una página web que contiene información sobre los diferentes niveles de optimización. Una cosa que recuerdas haber escuchado en alguna parte es que la optimización podría romper tu programa y eso puede ser un problema. Pero no estoy seguro de cuán grave es el problema. Quizás los compiladores de hoy son lo suficientemente inteligentes como para manejar esos problemas.
¿Cuál es la diferencia entre los diferentes niveles de optimización en GCC? Asumiendo que no me importa tener ningún gancho de depuración, ¿por qué no debería usar el nivel más alto de optimización disponible para mí? ¿un mayor nivel de optimización necesariamente (es decir, de manera demostrable) genera un programa más rápido?
Sí, un nivel más alto a veces puede significar un programa de mejor rendimiento. Sin embargo, puede causar problemas dependiendo de tu código. Por ejemplo, la predicción de bifurcación (habilitada en -O1 y superior) puede interrumpir programas de subprocesamiento múltiple mal escritos al causar una condición de carrera. La optimización realmente decidirá algo que es mejor que lo que escribió, que en algunos casos podría no funcionar.
Y a veces, las optimizaciones más altas (-O3) no agregan ningún beneficio razonable, sino un gran tamaño adicional. Sus propias pruebas pueden determinar si esta compensación de tamaño hace una ganancia de rendimiento razonable para su sistema.
Como nota final, el proyecto GNU compila todos sus programas en -O2 por defecto , y -O2 es bastante común en otros lugares.
Nota al margen:
Es bastante difícil predecir exactamente qué indicadores activan las directivas globales -O
en la línea de comandos gcc para diferentes versiones y plataformas, y toda la documentación en el sitio GCC es probable que se desactualice rápidamente o no cubra las partes internas del compilador en suficiente detalle
Aquí hay una manera fácil de verificar exactamente qué sucede en su configuración particular cuando usa uno de los indicadores -O
y otros -f
indicadores y / o combinaciones de los mismos:
- Crea un archivo fuente vacío en alguna parte:
touch dummy.c
- Ejecútelo aunque el compilador pase como lo haría normalmente, con todas las banderas
-O
,-f
y / o-m
que normalmente usaría, pero agregando-Q -v
a la línea de comando:
gcc -c -Q -v dummy.c
- Inspeccione la salida generada, quizás guardándola para una ejecución diferente.
- Cambie la línea de comando a su gusto, elimine el archivo de objeto generado a través de
rm -f dummy.o
y vuelva a ejecutar.
Además, siempre tenga en cuenta que, desde un punto de vista purista, la mayoría de las optimizaciones no triviales generan código "roto" (donde se define como desviado de la ruta óptima en casos de esquina), por lo que se elige si habilitar o no un determinado el conjunto de mecanismos de optimización a veces se reduce a elegir el nivel de corrección para la salida del compilador. Siempre ha habido (y actualmente hay) errores en el optimizador de compiladores, solo revisa la lista de correo de GCC y busca algunas muestras en Bugzilla. La optimización del compilador solo debe usarse después de realizar las mediciones desde
- las ganancias de usar un mejor algoritmo eclipsarán cualquier ganancia de la optimización del compilador,
- no tiene sentido optimizar el código que se ejecutará cada vez en una luna azul,
- si el optimizador introduce errores, no importa cuán rápido se ejecute su código.
En general, los niveles de optimización superiores a -O2
(solo -O3
para gcc pero otros compiladores tienen -O2
superiores) incluyen optimizaciones que pueden aumentar el tamaño de su código. Esto incluye cosas como desenrollar bucles, mucha alineación, relleno para alineación sin importar el tamaño, etc. Otros compiladores ofrecen vectorización y optimización interprocedimiento en niveles superiores a -O3
, así como ciertas optimizaciones que pueden mejorar la velocidad a costa de de corrección (por ejemplo, usando rutinas matemáticas más rápidas y menos precisas). Verifique los documentos antes de usar estas cosas.
En cuanto al rendimiento, es una compensación. En general, los diseñadores de compiladores intentan ajustar estas cosas para que no disminuyan el rendimiento de su código, por lo que -O3
generalmente ayudará (al menos en mi experiencia) pero su kilometraje puede variar. No siempre ocurre que las optimizaciones realmente agresivas que alteran el tamaño mejoran el rendimiento (por ejemplo, una alineación realmente agresiva puede generar contaminación en el caché).