Optimización del compilador


En informática , un compilador optimizador es un compilador que intenta minimizar o maximizar algunos atributos de un programa informático ejecutable . Los requisitos comunes son minimizar el tiempo de ejecución de un programa , la huella de memoria , el tamaño de almacenamiento y el consumo de energía (los últimos tres son populares para las computadoras portátiles ).

La optimización del compilador generalmente se implementa utilizando una secuencia de transformaciones de optimización , algoritmos que toman un programa y lo transforman para producir un programa de salida semánticamente equivalente que usa menos recursos o se ejecuta más rápido. Se ha demostrado que algunos problemas de optimización de código son NP-completos , o incluso indecidibles . En la práctica, factores como la voluntad del programador de esperar a que el compilador complete su tarea imponen límites superiores a las optimizaciones que un compilador puede proporcionar. La optimización es generalmente un proceso muy intensivo en CPU y memoria. En el pasado, las limitaciones de la memoria de la computadora también eran un factor importante para limitar las optimizaciones que se podían realizar.

Debido a estos factores, la optimización rara vez produce un resultado "óptimo" en ningún sentido y, de hecho, una "optimización" puede impedir el rendimiento en algunos casos. Más bien, son métodos heurísticos para mejorar el uso de recursos en programas típicos. [1]

Las técnicas utilizadas en la optimización se pueden dividir entre varios ámbitos que pueden afectar cualquier cosa, desde una sola declaración hasta todo el programa. En términos generales, las técnicas de alcance local son más fáciles de implementar que las globales, pero dan como resultado ganancias menores. Algunos ejemplos de alcances incluyen:

La siguiente es una instancia de una optimización dependiente de la máquina local. Para establecer un registro en 0, la forma obvia es usar la constante '0' en una instrucción que establece un valor de registro en una constante. Una forma menos obvia es aplicar XOR a un registro consigo mismo. Depende del compilador saber qué variante de instrucción usar. En muchas máquinas RISC , ambas instrucciones serían igualmente apropiadas, ya que ambas tendrían la misma longitud y tomarían el mismo tiempo. En muchos otros microprocesadores como el Intel x86familia, resulta que la variante XOR es más corta y probablemente más rápida, ya que no habrá necesidad de decodificar un operando inmediato, ni usar el "registro de operando inmediato" interno. Un problema potencial con esto es que XOR puede introducir una dependencia de datos en el valor anterior del registro, provocando un bloqueo de la canalización . Sin embargo, los procesadores a menudo tienen XOR de un registro consigo mismo como un caso especial que no provoca bloqueos.

En gran medida, las técnicas de optimización del compilador tienen los siguientes temas, que a veces entran en conflicto.