Diferente comportamiento de redondeo matemático entre Linux, Mac OS X y Windows.

HOLA,

Desarrollé algunos códigos mixtos C / C ++, con algunos cálculos numéricos intensivos. Cuando se comstack en Linux y Mac OS XI obtiene resultados muy similares después de que finaliza la simulación. En Windows, el progtwig también se comstack, pero obtengo resultados muy diferentes y, a veces, el progtwig no parece funcionar.

Utilicé comstackdores GNU en todos los sistemas. Algunos amigos me recomiendan agregar -frounding-math y ahora la versión de Windows parece funcionar más estable, pero Linux y Os X, sus resultados, no cambian en absoluto.

¿Podría recomendar otras opciones para obtener una mayor concordancia entre las versiones Win y Linux / OSX?

Gracias

PD También probé -O0 (sin optimizaciones) y especifiqué -m32

No puedo hablar de la implementación en Windows, pero los chips Intel contienen registros de punto flotante de 80 bits, y pueden brindar mayor precisión que la especificada en el estándar de punto flotante IEEE-754. Puede intentar llamar a esta rutina en la parte principal () de su aplicación (en plataformas con chip Intel):

inline void fpu_round_to_IEEE_double() { unsigned short cw = 0; _FPU_GETCW(cw); // Get the FPU control word cw &= ~_FPU_EXTENDED; // mask out '80-bit' register precision cw |= _FPU_DOUBLE; // Mask in '64-bit' register precision _FPU_SETCW(cw); // Set the FPU control word } 

Creo que esto es distinto de los modos de redondeo discutidos por @Alok.

Hay cuatro tipos diferentes de redondeo para números de punto flotante: redondear hacia cero, redondear hacia arriba, redondear hacia abajo y redondear al número más cercano. Dependiendo del comstackdor / sistema operativo, el valor predeterminado puede ser diferente en diferentes sistemas. Para cambiar programáticamente el método de redondeo, vea fesetround . Está especificado por el estándar C99, pero puede estar disponible para usted.

También puedes probar la opción gcc de la -ffloat-store . Esto intentará evitar que gcc utilice valores de punto flotante de 80 bits en los registros.

Además, si sus resultados cambian según el método de redondeo y las diferencias son significativas, significa que sus cálculos pueden no ser estables. Por favor considere hacer un análisis de intervalo, o usar algún otro método para encontrar el problema. Para obtener más información, consulte ¿Qué tan inútiles son las evaluaciones sin sentido de Roundoff en la computación de punto flotante? (pdf) y Los inconvenientes de verificar los cálculos de punto flotante (enlace ACM, pero puede obtener PDF desde muchos lugares si eso no funciona para usted).

Además de la configuración de redondeo de tiempo de ejecución que mencionaron las personas, puede controlar la configuración del comstackdor de Visual Studio en Propiedades> C ++> Generación de código> Modelo de punto flotante. He visto casos en los que establecer esto en “Rápido” puede causar algún mal comportamiento numérico (por ejemplo, los métodos iterativos no convergen).

La configuración se explica aquí: http://msdn.microsoft.com/en-us/library/e7s85ffb%28VS.80%29.aspx

Los estándares IEEE y C / C ++ dejan algunos aspectos de las matemáticas de punto flotante sin especificar. Sí, se determina el resultado exacto de agregar a flotadores, pero no es así un cálculo más complicado. Por ejemplo, si agrega tres flotadores, el comstackdor puede hacer la evaluación con precisión de flotación, doble precisión o superior. De manera similar, si agrega tres dobles, el comstackdor puede hacer la evaluación con una precisión doble o superior.

Por defecto, VC ++ establece que la precisión de las FPU x87 se duplique. Creo que gcc lo deja con una precisión de 80 bits. Ninguno es claramente mejor, pero pueden dar resultados diferentes, especialmente si existe alguna inestabilidad en sus cálculos. En particular, ‘pequeño + grande – grande’ puede dar resultados muy diferentes si tiene bits de precisión adicionales (o si el orden de la evaluación cambia). Las implicaciones de variar la precisión intermedia se discuten aquí:

http://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/

Los desafíos del punto flotante determinista se discuten aquí:

http://randomascii.wordpress.com/2013/07/16/floating-point-determinism/

Las matemáticas de punto flotante son complicadas. Debe averiguar cuándo los cálculos divergen y examinar el código generado para comprender por qué. Sólo entonces puedes decidir qué acciones tomar.