Pregunta

Mi aplicación está generando diferentes valores de punto flotante cuando la compilo en modo de lanzamiento y en modo de depuración. La única razón por la que me enteré es que guardo un registro de seguimiento binario y el de la versión de lanzamiento está ligeramente fuera de la versión de depuración, parece que los dos bits inferiores de los valores flotantes de 32 bits son diferentes aproximadamente 1/2 de los casos.

Considerarías esta " diferencia " Ser un error o este tipo de diferencia sería de esperar. ¿Sería esto un error del compilador o un error interno de la biblioteca?

Por ejemplo:

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

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

El problema está relacionado con el compilador X360.

¿Fue útil?

Solución

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.

Otros consejos

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

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

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

Ayudé a un compañero de trabajo a encontrar un conmutador de compilador que era diferente en las compilaciones de liberación frente a depuración que estaban causando sus diferencias.

Eche un vistazo a / fp (Especifique el punto flotante Comportamiento) .

No es un error. Cualquier incremento de punto flotante tiene cierta imprecisión. En el modo Release, la optimización cambiará el orden de las operaciones y obtendrá un resultado ligeramente diferente. Sin embargo, la diferencia debería ser pequeña. Si es grande, podría tener otros problemas.

Además de los diferentes modos de punto flotante que otros han señalado, SSE o optimizaciones de vectores similares pueden activarse para el lanzamiento. Convertir aritmética de punto flotante de registros estándar a registros vectoriales puede tener un efecto en los bits más bajos de sus resultados, ya que los registros vectoriales generalmente serán más estrechos (menos bits) que los registros estándar de punto flotante.

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

Por ejemplo, algunas plataformas tienen registros flotantes que utilizan más bits que los almacenados en la memoria, por lo que mantener un valor en el registro puede producir un resultado ligeramente diferente en comparación con el almacenamiento en la memoria y la recarga de la memoria.

Esta discrepancia puede deberse muy bien 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 podría causar una ligera diferencia en el resultado de punto flotante.

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

Como mencionan otros, los registros de punto flotante tienen mayor precisión que los flotantes, 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 resultará en resultados más lentos, menos precisos pero consistentes.

Si configura un conmutador de compilación que le 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 este tipo, es un error: los estándares C y C ++ no permiten que los compiladores reordenen las operaciones sin su permiso.

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