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.
fuente
Respuestas:
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.
fuente
FLT_EVAL_METHOD
en ISO C / C ++. Las funciones trascendentales (psin
. 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 nuevaglibc
versión) podría hacer que los resultados difieran.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) + c
puede o no ser igual aa + (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:
Números de puntos fijos:
fuente
(a + b * c) / d - e
. Exceptuando problemas obvios comoNaN
, 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.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.
fuente