Compilación con optimización

Para producir un programa que logre un buen rendimiento, el primer paso es aprovechar las características básicas de optimización incorporadas al compilador.

La compilación con optimización puede aumentar la aceleración derivada de ajustar el programa y puede eliminar la necesidad de realizar algún tipo de ajuste.

Recomendaciones

Siga estas directrices para la optimización:

  • Utilice -O2 u -O3 -qstrict para cualquier programa FORTRAN, C o C++ de nivel de producción que compile. Para los programas FORTRAN (HPF) de alto rendimiento, no utilice la opción -qstrict.
  • Utilice la opción -qhot para programas en los que las zonas activas son bucles o lenguaje de matriz. Utilice siempre la opción -qhot para programas HPF.
  • Utilice la opción -qipa cerca del final del ciclo de desarrollo si la hora de compilación no es una consideración importante.

La opción -qipa activa o personaliza una clase de optimizaciones conocidas como análisis entre procedimientos. La opción -qipa tiene varias subopciones que se detallan en el manual del compilador. Se puede utilizar de dos maneras:

  • El primer método es compilar con la opción -qipa durante los pasos de compilación y enlace. Durante la compilación, el compilador almacena información de análisis entre procedimientos en el archivo .o. Durante el enlace, la opción -qipa provoca una recompilación completa de toda la aplicación.
  • El segundo método consiste en compilar el programa para la creación de perfiles con la opción -p/-pg (con o sin -qipa) y ejecutarlo en un conjunto típico de datos. A continuación, los datos resultantes se pueden incorporar en compilaciones posteriores con -qipa para que el compilador concentre la optimización en los segundos del programa que se utilizan con más frecuencia.

El uso de -O4 es equivalente a utilizar -O3 -qipa con la generación automática de arquitectura y la opción de ajuste ideal para esa plataforma. El uso del distintivo -O5 es similar a -O4 excepto que -qipa= nivel = 2.

Obtendrá las ventajas siguientes cuando utilice la optimización del compilador:

Optimización de ramificaciones
Reorganiza el código de programa para minimizar la lógica de ramificación y combinar bloques de código físicamente separados.
Movimiento del código
Si las variables utilizadas en un cálculo dentro de un bucle no se alteran dentro del bucle, el cálculo se puede realizar fuera del bucle y los resultados se pueden utilizar dentro del bucle.
Eliminación de subexpresiones comunes
En expresiones comunes, el mismo valor se vuelve a calcular en una expresión posterior. La expresión duplicada se puede eliminar utilizando el valor anterior.
Propagación de constantes
Las constantes utilizadas en una expresión se combinan y se generan otras nuevas. Se realizan algunas conversiones implícitas entre tipos de enteros y de coma flotante.
Eliminación de código muerto
Elimina el código al que no se puede acceder o cuyos resultados no se utilizan posteriormente.
Eliminación del almacenamiento muerto
Elimina los almacenamientos cuando nunca se vuelve a hacer referencia el valor almacenado. Por ejemplo, si dos almacenamientos en la misma ubicación no tienen ninguna carga intermedia, el primer almacenamiento es innecesario y se elimina.
Asignación de registros globales
Asigna variables y expresiones a los registros de hardware disponibles utilizando un algoritmo de "coloreado gráfico".
En línea
Sustituye las llamadas de función por el código de programa real
Planificación de instrucciones
Reordena las instrucciones para minimizar el tiempo de ejecución
Análisis entre procedimientos
Descubre relaciones entre llamadas de función y elimina cargas, almacenamientos y cálculos que no se pueden eliminar con optimizaciones más sencillas.
Código IF flotante invariable (desconmutación)
Elimina el código de ramificación invariable de los bucles para crear más oportunidades para otras optimizaciones.
Retroalimentación impulsada por perfiles
Los resultados de la ejecución del programa de ejemplo se utilizan para mejorar la optimización de las ramificaciones condicionales y de las secciones de código ejecutadas con frecuencia.
Reasociación
Reorganiza la secuencia de cálculos en una expresión de subíndice de matriz, produciendo más candidatos para la eliminación de expresiones comunes.
Movimiento de almacenamiento
Mueve las instrucciones de almacenamiento fuera de los bucles.
Reducción de ineficacia
Sustituye las instrucciones menos eficientes por otras más eficientes. Por ejemplo, en el subíndice de matriz, una instrucción de adición sustituye una instrucción de multiplicación.
Numeración de valores
Implica la propagación constante, la eliminación de expresiones y la concentración de varias instrucciones en una sola instrucción.

Cuándo compilar sin optimización

No utilice la opción -O para los programas que desea depurar con un depurador simbólico, independientemente de si utiliza la opción -g. Sin embargo, debido a que la optimización es tan importante para los programas HPF, utilice -O3 -qhot para estos incluso durante la depuración.

El optimizador reorganiza las instrucciones del lenguaje ensamblador, por lo que es difícil correlacionar instrucciones individuales con una línea de código fuente. Si compila con la opción -g, esta reorganización puede dar la apariencia de que las sentencias de nivel fuente se ejecutan en el orden incorrecto cuando se utiliza un depurador simbólico.

Si el programa produce resultados incorrectos cuando se compila con cualquiera de las opciones de -O, compruebe el programa para ver si hay variables con alias involuntarios en las referencias de procedimiento.