Habilitación del modo de punto flotante estricto en GCC

6 minutos de lectura

avatar de usuario
Jordán

Todavía no he creado un programa para ver si GCC necesitará que se apruebe. Cuando lo haga, me gustaría saber cómo habilitaría el modo de punto flotante estricto que permitirá resultados reproducibles entre ejecuciones y computadoras. Gracias.

  • Tenga en cuenta que, debido a errores en el hardware, es posible que incluso forzar el modo estricto no proporcione resultados reproducibles. Y esos realmente suceden: cs.earlham.edu/~dusko/cs63/fpu.html, lwn.net/Artículos/89586, Reghardware.com/2006/04/28/amd_opteron_fpu_bug

    – liori

    3 sep 2011 a las 21:11


  • @liori Por “error”, quiere decir “ofrecer solo una mayor precisión que la doble precisión IEEE 754, de una manera muy conocida y documentada”. El hardware no tenía errores. No permite que los compiladores obtengan la semántica limpia de doble precisión IEEE 754 que desean, por supuesto, pero eso no es un error, solo una característica incorrecta.

    – Pascal Cuoq

    3 sep 2011 a las 21:15

  • @liori Debo señalar que escribí mi comentario antes de que agregaras los enlaces. Interesante. Retiro la parte “el hardware no tiene errores” de mi comentario.

    – Pascal Cuoq

    3 sep 2011 a las 21:15


  • @Pascal Cuoq: sí, en realidad agregué los enlaces porque pensé que alguien podría pensar de esta manera 🙂

    – liori

    3 sep 2011 a las 21:20

  • Incluso si hay errores de hardware, no veo cómo eso admite una posición de “punto flotante que no da resultados reproducibles”. Simplemente significa que algún hardware está roto y no debe usarse. ¿Diría que el prefijo de bloqueo x86 no brinda resultados reproducibles debido al error f00f? No, solo llamarías a la CPU que presenta el error defectuoso…

    – R.. GitHub DEJA DE AYUDAR A ICE

    03/09/2011 a las 21:30

avatar de usuario
Pascal Cuoq

Compilando con -msse2 en un procesador Intel/AMD que lo admita, casi lo logrará. No permita que ninguna biblioteca ponga la FPU en modo FTZ/DNZ, y la mayoría de las veces estará configurado (a pesar de los errores del procesador).

Para otras arquitecturas, la respuesta sería diferente. Aquellas arquitecturas que no ofrecen una forma conveniente de obtener la semántica IEEE 754 exacta (por ejemplo, CPU IA32 anteriores a SSE2) requerirían el uso de una biblioteca de emulación de coma flotante para obtener el resultado que desea, con una penalización de rendimiento muy alta.

Si su arquitectura de destino es compatible con la fmadd (multiplicación y suma sin redondeo intermedio), asegúrese de que su compilador no la use cuando tenga multiplicaciones y sumas explícitas en el código fuente. No se supone que GCC haga esto a menos que use la opción -ffast-math.

  • @highsciguy Dije “casi allí” porque el efecto secundario de -msse2 es hacer que sea más difícil, pero no imposible, que el compilador genere código no estrictamente IEEE 754 que generar código estrictamente IEEE 754. Todavía existe la posibilidad de que el compilador trabaje duro para romper la semántica de coma flotante. Para tomar un ejemplo caricaturesco, los desarrolladores de GCC pueden implementar la optimización “reemplazar división por constante en multiplicación por recíproco” en alguna versión, y luego alguien puede quejarse y esta optimización en particular puede trasladarse a la -ffast-math opción.

    – Pascal Cuoq

    23 de noviembre de 2012 a las 12:14


  • @highsciguy Para resumir, los creadores de compiladores generalmente no se preocupan lo suficiente como para poner este tipo de garantía por escrito, pero en el mejor de los casos escucharán si informa que un cambio que hicieron rompió la estricta semántica IEEE 754. Los resultados pueden depender de la versión precisa del compilador que se esté utilizando. Su mejor apuesta es usar -S -msse2 y leer el ensamblaje para comprobar si hay transformaciones incorrectas. Con el conjunto de instrucciones históricas, es algo inútil: algunos detalles se pueden encontrar en gcc.gnu.org/ml/gcc-patches/2008-11/msg00105.html

    – Pascal Cuoq

    23 de noviembre de 2012 a las 12:17


  • También es posible que desee ver el valor que su compilador establece macro FLT_EVAL_METHOD para. Esta macro la establece el compilador. Ver también FP_CONTRACT (establecido por el programador).

    – Pascal Cuoq

    23 de noviembre de 2012 a las 12:33


  • @PascalCuoq: Desearía que los lenguajes incluyeran diferentes operadores estrictos y no estrictos, ya que muchos algoritmos requieren que se realicen algunos pasos clave con semántica estricta, pero podrían tolerar una semántica más flexible en otros pasos [e.g. because a +/- 1lsb error on one step would get cancelled out in the next step]. Si el 25% de los pasos en un algoritmo deben ser precisos, sería mejor llamar a ese 25% y dejar que las otras operaciones se ejecuten más rápido, que hacer que todo se ejecute lentamente.

    – Super gato

    04/06/2014 a las 17:25

  • @supercat Como alguien con poco interés en el punto flotante que por primera vez el mes pasado escribió un algoritmo numéricamente estable en el que realmente deseaba que el compilador reemplazara las multiplicaciones y sumas con FMA, estoy totalmente de acuerdo. Hasta donde yo sé, GCC todavía no permite seleccionar un modo u otro a una escala inferior a la unidad de compilación.

    – Pascal Cuoq

    04/06/2014 a las 18:01

Si utiliza -ffloat-store y siempre almacene valores intermedios a las variables o aplique conversiones (explícitas) al tipo/precisión deseado, debe estar al menos en un 90% de su objetivo, y tal vez más. Agradecería comentarios sobre si hay casos en los que este enfoque aún no se detecta. Tenga en cuenta que afirmo que esto funciona incluso sin ninguna opción de SSE.

  • Dos palabras: “doble redondeo” explorandobinary.com/…

    – Pascal Cuoq

    3 sep 2011 a las 21:31


  • Buen punto. Personalmente, cuando necesito un comportamiento de punto flotante exacto, solo uso long double para todo…

    – R.. GitHub DEJA DE AYUDAR A ICE

    3 de septiembre de 2011 a las 21:43

  • Esa es una buena solución, pero ya no es portátil entre computadoras que no tienen 80 bits long doubles. Ahora que lo pienso, me pregunto si el OP, cuando dice “computadoras”, realmente significa entre arquitecturas, o solo entre procesadores dentro de una arquitectura dada (en cuyo caso debería estar seguro).

    – Pascal Cuoq

    3 sep 2011 a las 21:54


  • Otra forma de evitar problemas de doble redondeo es usar un modo de redondeo diferente, por ejemplo fesetround(FE_TOWARDZERO)… 🙂

    – R.. GitHub DEJA DE AYUDAR A ICE

    4 de septiembre de 2011 a las 0:07

  • Por lo que vale, encontré que -ffloat-store con GCC acordó con Microsoft en /fp:precise modo. Lo cual es algo bueno.

    – Pedro M.

    18 de noviembre de 2013 a las 18:47


avatar de usuario
Yann Droneaud

También puedes usar GCCla opcion de -mpc64 en el objetivo i386 / ia32 para forzar el cálculo de doble precisión incluso en x87 FPU. Ver manual de CCG.

También puede modificar el comportamiento de la FPU x87 en tiempo de ejecución, consulte Aritmética de coma flotante multiplataforma determinista y también Una introducción a GCC.

  • El artículo “multiplataforma determinista” en particular es excelente. ¡Gracias!

    – Pedro M.

    18 de noviembre de 2013 a las 18:48


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad