2008-09-26 9 views
6

Mi aplicación genera diferentes valores de coma flotante cuando los compilo en modo de lanzamiento y en modo de depuración. La única razón por la que descubrí es que guardo un registro de rastreo binario y el de la versión de lanzamiento está ligeramente alejado de la compilación de depuración, parece que los dos bits inferiores de los valores de flotación de 32 bits son diferentes a 1/2 de los casos.Los valores de Float se comportan de forma diferente en las compilaciones de versión y depuración

Consideraría esta "diferencia" como un error o se esperaría este tipo de diferencia. ¿Sería esto un error del compilador o un error de la biblioteca interna?

Por ejemplo:

LEFTPOS and SPACING are defined floating point values. 
float def_x; 
int xpos; 

def_x = LEFTPOS + (xpos * (SPACING/2)); 

La cuestión es en cuanto a que el compilador X360.

Respuesta

11

El modo de liberación puede tener un conjunto de estrategias de FP diferente. Existen diferentes modos aritméticos de punto flotante según el nivel de optimización que desee. MSVC, por ejemplo, tiene modos estrictos, rápidos y precisos.

2

No es un error. Cualquier operación de punto flotante tiene una cierta imprecisión. En el modo de lanzamiento, la optimización cambiará el orden de las operaciones y obtendrá un resultado ligeramente diferente. La diferencia debería ser pequeña, sin embargo. Si es grande, es posible que tenga otros problemas.

3

Ayudé a un compañero de trabajo a encontrar un cambio en el compilador que era diferente en las versiones de versión y depuración que causaban sus diferencias.

Eche un vistazo a /fp (Specify Floating-Point Behavior).

1

No es un error. Este tipo de diferencia es de esperar.

Por ejemplo, algunas plataformas tienen registros flotantes que usan más bits que los almacenados en la memoria, por lo que mantener un valor en el registro puede arrojar resultados ligeramente diferentes en comparación con almacenar en la memoria y volver a cargar desde la memoria.

0

Esta discrepancia puede deberse a la optimización del compilador, que normalmente se realiza en el modo de lanzamiento, pero no en el modo de depuración. Por ejemplo, el compilador puede reordenar algunas de las operaciones para acelerar la ejecución, lo que posiblemente puede causar una ligera diferencia en el resultado del punto flotante.

Por lo tanto, diría que lo más probable es que no sea un error. Si realmente está preocupado por esto, intente activar la optimización en el modo de depuración.

4

Sé que en la PC, los registros de coma flotante tienen 80 bits de ancho. Entonces, si un cálculo se hace completamente dentro de la FPU, obtendrá el beneficio de 80 bits de precisión. Por otro lado, si un resultado intermedio se mueve a un registro normal y viceversa, se trunca a 32 bits, lo que arroja resultados diferentes.

Ahora considere que una versión de lanzamiento tendrá optimizaciones que mantienen los resultados intermedios en registros FPU, mientras que una versión de depuración probablemente ingenuamente copiará los resultados intermedios entre la memoria y los registros, y ahí tiene su diferencia de comportamiento.

No sé si esto también ocurre en X360 o no.

0

Como otros mencionados, los registros de coma flotante tienen mayor precisión que los flotadores, por lo que la precisión del resultado final depende de la asignación del registro.

Si necesita resultados consistentes, puede hacer que las variables sean volátiles, lo que dará como resultado resultados más lentos, menos precisos pero consistentes.

2

Además de los diferentes modos de punto flotante que otros han señalado, SSE u otras optimizaciones similares pueden activarse para su lanzamiento. La conversión de aritmética de coma flotante de registros estándar a registros vectoriales puede tener un efecto en los bits más bajos de los resultados, ya que los registros vectoriales generalmente serán más angostos (menos bits) que los registros estándar de coma flotante.

0

Si configura un compilador que permite al compilador reordenar las operaciones de punto flotante, por ejemplo,/fp: rápido, entonces obviamente no es un error.

Si no configuró ningún interruptor de ese tipo, entonces es un error: los estándares C y C++ no permiten que los compiladores reordenen las operaciones sin su permiso.

Cuestiones relacionadas