¿Todavía necesito usar un punto fijo para garantizar que las computadoras obtengan el mismo resultado para las operaciones matemáticas?

9

Me dijeron que la mayoría de las computadoras modernas siguen el mismo estándar de coma flotante, ¿significa esto que todas obtendrán la misma respuesta flotante para una operación matemática dada si las entradas son las mismas?

Pregunto porque estoy investigando para hacer un juego de estrategia en tiempo real en una red, y sincronizar cientos de posiciones de unidades parece un mal camino a seguir.

Entonces, si solo envío entradas, necesito garantizar que todos los clientes obtengan el mismo resultado al hacer que ejecuten la simulación desde esas entradas.

Leí que los juegos RTS más antiguos usaban aritmética de punto fijo, pero no sé si eso todavía se requiere en las computadoras modernas si todas cumplen con el mismo estándar. También me dijeron que, aunque impreciso, el resultado del punto flotante es determinista para la misma entrada (lo que supongo que significa que cualquier computadora que siga el mismo estándar obtiene el mismo resultado impreciso).

¿Las computadoras aún tienen desviaciones incluso si siguen el mismo estándar de coma flotante?

Estoy escribiendo este juego en C #, aunque no estoy seguro de si eso importa, pensé en mencionarlo de todos modos.

WDUK
fuente
Incluso si lo hicieran, no usaría flotadores para eso
Telastyn
Qué quieres decir ? Por qué no?
WDUK
El uso de flotadores puede ser indeseable de todos modos porque el comportamiento puede depender de la posición en el mapa. Las Tierras lejanas de Minecraft fueron un ejemplo más notable: el movimiento, el renderizado y la generación del terreno se volverían problemáticos a medida que te alejases del punto de generación.
amon

Respuestas:

18

¿Las computadoras aún tienen desviaciones incluso si siguen el mismo estándar de coma flotante?

Desafortunadamente, sí, especialmente cuando usa C # (u otro lenguaje compilado JIT). El problema que ocurre aquí es que la etapa de compilación JIT en algunas arquitecturas de procesador produce código que usa más registros de CPU que en otras arquitecturas. Esto puede conducir a situaciones en las que en algunas máquinas, la precisión de coma flotante extendida se utiliza para ciertas operaciones, mientras que en otras máquinas no. Esto significa que para cada cálculo iterativo que use dobles, existe la posibilidad de producir diferentes errores de redondeo acumulados.

Ese no es un problema hipotético, tengo experiencia de primera mano con tales desviaciones en el software de simulación de ingeniería contemporáneo, en hardware más o menos moderno. Este problema hace que sea realmente difícil crear pruebas de regresión confiables para cálculos complejos de coma flotante que produzcan exactamente el mismo resultado en todas las máquinas involucradas.

Doc Brown
fuente
Esta. Algunas causas fundamentales: IEEE Std 754 incluye cláusulas opcionales "debería" (por ejemplo, manejo de NaN) y permite alternativas de diseño (por ejemplo, detección de flujo insuficiente). En la medida en que los enlaces de lenguaje soporten el estándar de punto flotante, aún pueden dar margen al compilador al evaluar expresiones de punto flotante, por ejemplo, FLT_EVAL_METHODen ISO C / C ++. Las funciones trascendentales (p sin. Ej . exp, log) No están reguladas en gran medida tanto por el estándar de coma flotante IEEE como por los estándares del lenguaje de programación. Una simple actualización de la versión de la biblioteca (p. Ej., Una nueva glibcversión) podría hacer que los resultados difieran.
njuffa
Lo golpeé yo mismo en un juego. El cohete voló bien en mi computadora portátil, no volaría en mi escritorio, instalaciones completamente idénticas.
Loren Pechtel
3

Errores de coma flotante

Cada número de coma flotante acumula imprecisión a medida que se usa para el cálculo. Este es un hecho simple de usar un formato impreciso para calcular. Los cálculos también son sensibles al orden de cálculo, la conmutatividad no está garantizada, es decir: (a + b) + cpuede o no ser igual a a + (b + c).

Además, los procesadores no tienen necesariamente la misma longitud de mantisa que el estándar de memoria. Esto puede generar un comportamiento interesante ya que el flotante de 32/64/128 bits ocasionalmente funciona como si tuviera más bits.

Errores de punto fijo

Dicho esto, la aritmética de punto fijo también puede acumular errores. La diferencia es que los números de puntos fijos son claros acerca de qué precisión se pierde y, dependiendo de las operaciones elegidas, se pueden evitar por completo los errores de redondeo. También son conmutativos (a + b) + c = a + (b + c).

¿Cuales?

Cuál usar depende completamente de las propiedades que necesita.

Números de punto flotante:

  • dan una amplia gama de valores que se vuelven muy finos de cerca y progresivamente más separados en los extremos.
  • son sensibles al orden de cálculo
  • acumular errores de redondeo con el tiempo.
  • puede tener un comportamiento errático debido a la falta de coincidencia de tamaño de flotante de hardware / memoria.

Números de puntos fijos:

  • dé un rango menor de números con la misma distancia entre dos números consecutivos.
  • son menos sensibles al orden de cálculo
  • son más claros acerca de los errores de redondeo
  • se puede trabajar para minimizar / evitar problemas de redondeo.
Kain0_0
fuente
1
"Los números de punto fijo son claras acerca de lo que se pierde precisión" - puntos flotantes son claras imprecisiones puntuales también, la diferencia es más bien fijos son más intuitivo a la numeración de la vida ordinaria
Whatsisname
1
Entonces, ¿solo el punto fijo garantiza que todas las computadoras independientemente del hardware, etc. experimentarán los mismos errores / pérdida de precisión?
WDUK
1
Esencialmente, sí, porque puede especificar que sus números de punto fijo sean 32 o 64 bits, y estarán en todos los sistemas. Los números de coma flotante pueden ser de 32 o 64 bits, pero el hardware puede usar 48 o 96 bits para hacer el cálculo y convertirlos a 32 o 64 bits al final, lo que resulta en diferencias entre los diferentes tipos de hardware.
user1118321
@whatsisname Mientras que las especificaciones de punto flotante son muy claras, que no me puede decir fácilmente qué temas redondeo que se utilizan en este resumen: (a + b * c) / d - e. Exceptuando problemas obvios como NaN, división por cero, o desbordamiento / subflujo, es posible que esta expresión sea incorrecta. Agregue a eso la impedancia entre la memoria y el registro en términos de precisión e incluso una simple carga / almacenamiento desde la memoria del "mismo" valor de punto flotante cambiará la respuesta.
Kain0_0
@ Kain0_0: tienes razón, no puedo decirte fácilmente con qué me encontraré, porque no soy un experto en coma flotante. Eso es exactamente lo que quería decir cuando dije "más intuitivo para la numeración de la vida ordinaria". Cuando dice que el punto fijo es "claro" y el punto flotante no lo es, lo hace sonar como si los flotadores fueran aparentemente imprecisos al azar.
whatsisname
-1

Existe la pregunta de por qué querría garantizar resultados idénticos, ya que los resultados idénticos no garantizan en absoluto que sus resultados sean útiles .

Podría tener un algoritmo numéricamente inestable que proporcione dos resultados idénticos pero completamente sin sentido en diferentes computadoras. Si hay diferencias, pero los resultados son los mismos dentro de 13 dígitos, eso es mucho más confiable.

Hay muy pocas situaciones en las que la reproducibilidad sea realmente importante: en un motor de diseño o compresión / descompresión sin pérdidas. Es muy probable que el uso de un punto fijo sea erróneo.

gnasher729
fuente
No rechacé su respuesta, pero parece que el caso descrito por el OP es exactamente "una de esas pocas situaciones en las que la reproducibilidad es realmente importante". En un juego RTS, un pequeño error de redondeo puede marcar la diferencia entre "dos objetos colisionados" o no.
Doc Brown