Optimización interprocedimiento

Optimización interprocedimiento ( ing.  Interprocedural O ptimization , IPO ), u optimización de programa completo de programas ( ing.  optimización de programa completo ): optimización del compilador que utiliza análisis de flujo de control global y afecta muchos procedimientos, incluso aquellos ubicados en diferentes módulos, debido a la que se puede lograr un aumento significativo en la velocidad.

A medida que los programas crecían en tamaño, los desarrolladores comenzaron a hacer que su código fuera más legible y reutilizable . A menudo, esto lleva al hecho de que los procedimientos se vuelven extremadamente generales, mientras que en un programa específico puede arreglárselas con un caso especial. La tarea de la optimización interprocesal es precisamente la generación de tales casos especiales.

El compilador realiza automáticamente la optimización entre procedimientos (a veces con directivas especiales). Activarlo puede conducir a un aumento significativo en el tiempo de compilación. Los compiladores que pueden realizar esta optimización incluyen MLton y MLKit para Standard ML , Stalin para Scheme , para Haskell , Intel C++ Compiler .

Ejemplos

Reemplazo de un parámetro de función con una constante

Después de recorrer el código, el compilador se asegura de que uno de los parámetros sea siempre una constante y lo destruye.

Fue void HacerAlgo ( Objeto * aObj , int aParam ) { si ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "HacerAlgo(" << aObj -> nombre () << "," << aParam << ")" << endl ; } int principal () { Objeto obj1 , obj2 ; HazAlgo ( & obj1 , 1 ); HazAlgo ( & obj2 , 1 ); devolver 0 ; } Se convirtió en void HacerAlgo ( Objeto * aObj ) { si ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "HacerAlgo(" << aObj -> nombre () << "," << 1 << ")" << endl ; } int principal () { Objeto obj1 , obj2 ; Hacer Algo ( & obj1 ); Hacer Algo ( & obj2 ); devolver 0 ; }

Sustitución de una llamada virtual por una estática

Aquí es donde el compilador se asegura de que todas las llamadas virtuales que se ejecutan realmente conduzcan a la misma llamada de función. En lugar de acceder a la tabla de métodos virtuales , el compilador realiza una llamada de función directa.

En el mismo ejemplo, si Object::name() es un método virtual, la función optimizada se vería así.

void HacerAlgo ( Objeto * aObj ) { si ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "HacerAlgo(" << Objeto :: nombre ( aObj ) << "," << 1 << ")" << endl ; }

Eliminando código no utilizado

Después de la eliminación obtienes:

void HacerAlgo ( Objeto * aObj ) { cout << "HacerAlgo(" << Objeto :: nombre ( aObj ) << "," << 1 << ")" << endl ; }

Al mismo tiempo, se pueden borrar las tablas de métodos virtuales .

Inline

Si una función se usa una vez, se incluye directamente en el lugar desde el que se llama.

También se pueden incluir funciones pequeñas directamente en el código de llamada.

Muchos lenguajes de programación ( Pascal , Java , D ) no tienen la palabra clave inline , y la decisión de incorporar una función la toma el optimizador (en el caso de Java  , el ofuscador ).

Fue en línea int Hacer Algo ( int aParam ) { return aParam * aParam ; } int principal () { int x = 2 ; int y = 3 ; cout << x << "^2=" << HacerAlgo ( x ) << " , " << y << "^2=" << HacerAlgo ( y ) << endl ; devolver 0 ; } Se convirtió en int principal () { int x = 2 ; int y = 3 ; cout << x << "^2=" << x * x << ", " << y << "^2=" << y * y << endl ; devolver 0 ; }

Enlaces

  • Thomas C. Spillman, "Exposición de efectos secundarios en un compilador de optimización PL/I", en Actas de IFIPS 1971 , North-Holland Publishing Company, páginas 376-381.
  • Frances E. Allen, "Análisis de flujo de datos entre procedimientos", Actas de IFIPS, 1974.
  • Frances E. Allen y Jack Schwartz, "Determinación de las relaciones de flujo de datos en una colección de procedimientos", IBM Research Report RC 4989, agosto de 2010. 1974.
  • Philip Abrams , "An APL Machine", Departamento de Ciencias de la Computación de la Universidad de Stanford, Informe STAN-CS-70-158, febrero de 1970.
  • Terrence C. Miller, "Compilación tentativa: un diseño para un compilador APL", Ph.D. Tesis, Universidad de Yale, 1978.