Las optimizaciones pueden realizarse de diferentes formas. Las optimizaciones se realizan en base al alcance ofrecido por el compilador. La optimización va a depender del lenguaje de programación y es directamente proporcional al tiempo de compilación; es decir, entre más optimización mayor tiempo de compilación. La optimización es un proceso que tiene a minimizar o maximizar alguna variable de rendimiento, generalmente tiempo, espacio, procesador, etc. 

3.1.1 Locales 

La optimización local se realiza sobre módulos del programa. En la mayoría de las ocasiones a través de funciones, métodos, procedimientos, clases, etc. La característica de las optimizaciones locales es que solo se ven reflejados en dichas secciones. La optimización local sirve cuando un bloque de programa o sección es crítico por ejemplo: E/S, la concurrencia, la rapidez y confiabilidad de un conjunto de instrucciones. Como el espacio de soluciones es más pequeño la optimización local es más rápida. Como el espacio de soluciones es más pequeño la optimización local es más rápida. 

• Las optimizaciones locales se realizan sobre el bloque básico

• Optimizaciones locales

– Folding

– Propagación de constantes

– Reducción de potencia

– Reducción de subexpresiones comunes

Bloque Básico

• Un bloque básico es un fragmento de código que tiene una única entrada y salida, y cuyas instrucciones se ejecutan secuencialmente. Implicaciones:

– Si se ejecuta una instrucción del bloque se ejecutan todas en un orden conocido en tiempo de compilación.

• La idea del bloque básico es encontrar partes del programa cuyo análisis necesario para la optimización sea lo más simple posible.



Ensamblamiento (Folding)

• El ensamblamiento es remplazar las expresiones por su resultado cuando se pueden evaluar en tiempo de compilación (resultado constante).

– Ejemplo: A=2+3+A+C -> A=5+A+C

• Estas optimizaciones permiten que el programador utilice cálculos entre constantes representados explícitamente sin introducir ineficiencias.


Implementación del Folding

• Implementación del floding durante la generación de código realizada conjuntamente con el análisis sintáctico.

– Se añade el atributo de constante temporal a los símbolos no terminales y a las variables de la tabla de símbolos.

– Se añade el procesamiento de las constantes a las reglas de análisis de expresiones.

– Optimiza: 2+3+b -> 5+b

• Hay una suma de constantes (2+3)+b

– No optimiza: 2+b+3 -> 2+b+3

• No hay una suma de constantes (2+b)+3


Implementación del Folding

• Implementación posterior a la generación de código

– Buscar partes del árbol donde se puede aplicar la propiedad conmutativa:

• Sumas/restas: como la resta no es conmutativa se transforma en sumas: a+b-c+d -> a+b+(-c)+d

• Productos/divisiones: como la división no es conmutativa se transforma en productos: a*b/c*e -> a*b*(1/c)*e

– Buscar las constantes y operarlas

– Reconstruir el árbol.



3.1.2 Ciclos 

Los ciclos son una de las partes más esenciales en el rendimiento de un programa dado que realizan acciones repetitivas, y si dichas acciones están mal realizadas, el problema se hace N veces más grandes. La mayoría de las optimizaciones sobre ciclos tratan de encontrar elementos que no deben repetirse en un ciclo. 

Sea el ejemplo: 

while(a == b) { 

int c = a; 

c = 5;

 …; }

 En este caso es mejor pasar el Int c =a; fuera del ciclo de ser posible. El problema de la optimización en ciclos y en general radica es que muy difícil saber el uso exacto de algunas instrucciones. Así que no todo código de proceso puede ser optimizado. Otros uso de la optimización pueden ser el mejoramiento de consultas en SQL o en aplicaciones remotas (sockets, E/S, etc.) 

3.1.3 Globales 

La optimización global se da con respecto a todo el código. Este tipo de optimización es más lenta pero mejora el desempeño general de todo programa. Las optimizaciones globales pueden depender de la arquitectura de la máquina. En algunos casos es mejor mantener variables globales para agilizar los procesos (el proceso de declarar variables y eliminarlas toma su tiempo) pero consume más memoria. Algunas optimizaciones incluyen utilizar como variables registros del CPU, utilizar instrucciones en ensamblador. 

3.1.4 De mirilla 

La optimización de mirilla trata de estructurar de manera eficiente el flujo del programa, sobre todo en instrucciones de bifurcación como son las decisiones, ciclos y saltos de rutinas. La idea es tener los saltos lo más cerca de las llamadas, siendo el salto lo más pequeño posible. Instrucciones de bifurcación Interrumpen el flujo normal de un programa, es decir que evitan que se ejecute alguna instrucción del programa y salta a otra parte del programa. 

Por ejemplo: el “break” 

Switch (expresión que estamos evaluando) 

Case 1: cout << “Hola” ; 

Break; 

Case 2: cout << “amigos”; 

Break; 

}

ESTE SITIO FUE CONSTRUIDO USANDO