2010-04-29 24 views
5

Tengo un problema extraño. He siguiente fragmento de código:Optimización del compilador que hace que el rendimiento se ralentice

template<clss index, class policy> 
inline int CBase<index,policy>::func(const A& test_in, int* srcPtr ,int* dstPtr) 
{ 
    int width = test_in.width(); 
    int height = test_in.height(); 

    double d = 0.0; //here is the problem 
    for(int y = 0; y < height; y++) 
    { 

     //Pointer initializations 

     //multiplication involving y 
     //ex: int z = someBigNumber*y + someOtherBigNumber; 
     for(int x = 0; x < width; x++) 
     { 
      //multiplication involving x 
     //ex: int z = someBigNumber*x + someOtherBigNumber; 
      if(soemCondition) 
      { 
       // floating point calculations 
      } 
      *dstPtr++ = array[*srcPtr++]; 
     } 
    } 
} 

El bucle interno es ejecutado cerca de 200.000 veces y la función entera tarda 100 ms para su conclusión. (perfilado con AQTimer)

Encontré una variable no utilizada double d = 0.0; fuera del bucle exterior y eliminé la misma. Después de este cambio, de repente el método está tomando 500ms para el mismo número de ejecuciones. (5 veces más lento).

Este comportamiento es reproducible en diferentes máquinas con diferentes tipos de procesadores. (Core2, procesadores dualcore).

Estoy usando el compilador VC6 con el nivel de optimización O2. siguientes aparatos son las otras opciones del compilador utilizados:

-MD -O2 -Z7 -GR -GX -G5 -X -GF -EHa 

sospeché optimizaciones del compilador y quitó la optimización del compilador /O2. Después de que la función se volvió normal y está tomando 100ms como código anterior.

¿Alguien podría arrojar algo de luz sobre este extraño comportamiento?

¿Por qué la optimización del compilador debería ralentizar el rendimiento cuando elimino la variable no utilizada?

Nota: El código de ensamblaje (antes y después del cambio) se veía igual.

+1

¿Estás seguro de que el conjunto se veía igual? ¿"Se ve igual" o es * exactamente * lo mismo? – jalf

+0

es exactamente lo mismo. –

Respuesta

5

Si el código de ensamblaje se ve igual antes y después del cambio, el error está de alguna manera conectado a cómo se sincroniza la función.

1

Declare width y height como const {unsigned} ints. {Se debe usar sin signo, ya que las alturas y el ancho nunca son negativos.}

const int width = test_in.width(); 
const int height = test_in.height(); 

Esto ayuda con el compilador de optimización. Con los valores como const, puede colocarlos en el código o en los registros, sabiendo que no cambiarán. Además, alivia al compilador de tener que adivinar si las variables cambian o no.

Sugiero imprimir el código de ensamblaje de las versiones sin usar double y sin. Esto le dará una idea del proceso de pensamiento del compilador.

4

VC6 tiene errores. Se sabe que genera código incorrecto en varios casos, y su optimizador tampoco es tan avanzado. El compilador tiene más de una década y ni siquiera se ha admitido durante muchos años.

Así que en realidad, la respuesta es "estás usando un compilador defectuoso. Espera un comportamiento con errores, especialmente cuando las optimizaciones están habilitadas".

No creo que la actualización a un compilador moderno (o simplemente probar el código en uno) sea una opción.

Obviamente, el ensamblaje generado no puede ser el mismo, o no habría diferencia de rendimiento.

La única pregunta es donde es la diferencia. Y con un compilador con errores, puede ser una parte del código que no se relaciona y que de repente se compila de manera diferente y se rompe. Sin embargo, lo más probable es que el código de ensamblado generado para esta función sea no, y las diferencias son tan sutiles que no las notó.

+0

Vamos a tomar una conjetura descabellada y a decir que el doble forzó a las rutinas de puntos flotantes posteriores a alinearse en 8 bytes, lo que puede mejorar notablemente el rendimiento cuando se usan dobles. –

+0

sí, eso es posible. Es probable que los problemas de alineación den cuenta de una desaceleración de esta magnitud – jalf

+0

, desafortunadamente es un gran proyecto heredado. Mucho esfuerzo involucrado en la migración al último VC :( –

Cuestiones relacionadas