Pregunta

Estoy teniendo un problema real extraño usando GCC para ARM con las optimizaciones encendidos. Compilar mi aplicación C ++ sin las optimizaciones produce un ejecutable que en tiempo de ejecución da salida a los resultados esperados. Tan pronto como enciendo la optimizaciones - es decir -O1 - mi solicitud no produce los resultados esperados. He intentado durante un par de días para detectar el problema, pero no tengo ni idea. Eliminé cualquier variable sin inicializar de mi código, he corregido los puntos donde aliasing estricta podría causar problemas, pero todavía no tengo los resultados adecuados.

estoy usando GCC 4.2.0 para ARM (el procesador es un ARM926EJ-s) y ejecuta la aplicación en una distribución Linux Montavista.

A continuación se presentan las banderas que estoy usando:

-O1 -fno-unroll-loops fno-merge-constants -fno-omit-frame-pointer -fno-toplevel-reorder \
-fno-defer-pop -fno-function-cse -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=3 \
-fsigned-char -march=armv5te -mtune=arm926ej-s -ffast-math

Tan pronto como me tira la bandera -O1 y recompilar / vincular la aplicación me da los resultados de salida adecuados. Como se puede ver en las banderas Traté de desactivar cualquier optimización pensé que podría causar problemas, pero sigue sin suerte.

¿alguien tiene alguna sugerencias sobre cómo podría hacer frente aún más este problema?

Gracias

¿Fue útil?

Solución

En general, si usted dice "optimización rompe mi programa", es el 99,9% de su Programm que se rompe. Habilitación de optimizaciones única destapa los fallos en su código.

También debe ir fácil en las opciones de optimización. Sólo en circunstancias muy específicas que se necesita nada más allá de las opciones estándar -O0, O2, O3 y quizás -os. Si se siente lo ¿Necesita una configuración más específico que eso, prestar atención en el mantra de optimizaciones:

Medida, optimizar medida.

No ir por "primera impresión" aquí. Demostrar que una opción de optimización no estándar determinado beneficia significativamente su aplicación, y entender por qué (es decir, entender exactamente lo que hace esa opción, y por qué afecta su código).

Esto no es un buen lugar para navegar vendaron los ojos.

Y ver cómo se utiliza la opción más defensivo (-O1), a continuación, desactivar la mitad de una docena de optimizaciones, y después añadir -ffast-matemáticas, me lleva a asumir que estás haciendo actualmente sólo eso .

Bueno, tal vez de un solo ojo.

Pero la conclusión es:. Si lo cual permite optimizar rompe su código, lo más probable es culpa de su código

EDIT: acabo de encontrar esto en el manual de GCC:

  

-ffast-math: Esta opción no debe ser encendido por ninguna opción -O    ya que puede dar lugar a resultados incorrectos para los programas que dependen de   una implementación exacta de normas IEEE o ISO / especificaciones para las matemáticas   funciones.

Esta Qué dice, básicamente, que su -O1 -ffast-math hecho podría romper correcta código. Sin embargo, incluso si quitando -ffast-math elimina su problema actual, al menos debe tener una idea ¿Por qué . De lo contrario podría simplemente intercambiar su problema ahora con un problema en un momento más inconveniente después (como cuando se rompe el Producto en el domicilio de su cliente). ¿Es realmente -ffast-math que era el problema, o no se ha roto el código de matemáticas que es descubiertos por -ffast-math?

Otros consejos

-ffast-math se debe evitar si es posible. Sólo tiene que utilizar -O1 por ahora y soltar todos los otros interruptores de optimización. Si sigue apareciendo problemas entonces es el momento para iniciar la depuración.

Sin ver su código, es difícil conseguir más específico que "es probable que tenga un error".

Existen dos escenarios en los que permite optimizaciones cambia la semántica del programa:

  • hay un error en el compilador, o
  • hay un error en el código.

Esta última es probablemente la más probable. En concreto, es probable que confiar en algún lugar un comportamiento indefinido en su programa. Que se basan en algo que sólo para pasar a ser cierto cuando se compila utilizando este compilador de este equipo con estas opciones del compilador, pero que ISN' t garantizada por el lenguaje. Y así, cuando se habilita optimizaciones, GCC no tiene ninguna obligación de preservar ese comportamiento.

Nos muestran su código. O paso a través de él en el depurador hasta llegar al punto en que las cosas van mal.

No puedo ser más específico. Puede ser que sea un puntero colgando, las variables sin inicializar, rompiendo las reglas de alias, o incluso simplemente haciendo una de las muchas cosas que el rendimiento de las llamativas resultados (como i = i++)

Trate de hacer un caso de prueba mínima. Modificar el programa, la eliminación de las cosas que no afectan el error. Es probable que usted descubrirá el error a sí mismo en el proceso, pero si no lo hace, usted debe tener un programa de ejemplo de una pantalla en la que puede de correos.

Por cierto, si , como otros han especulado, es -ffast-math que hace que su problema (es decir, la compilación con sólo -O1 bien funciona), entonces es probable que usted tiene un poco de matemática en allí se debe reescribir todos modos . Es un poco de una simplificación excesiva, pero -ffast-math permite que el compilador cálculos esencialmente Reordenar como se podía números matemáticos abstractos - a pesar de hacerlo en el hardware real puede causar resultados ligeramente diferentes ya que los números de punto flotante no son exactas. Basándose en ese tipo de detalles de punto flotante es probable que sea intencional.

Si se quiere entender el insecto, un caso de prueba mínima es crítico en cualquier caso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top