2010-04-27 5 views
8

Estoy escribiendo un videojuego, Humm and Strumm, que requiere un componente de red en su motor de juego. Puedo lidiar con las diferencias en endianness fácilmente, pero me he topado con una pared al tratar de lidiar con los posibles formatos de memoria float. Sé que las computadoras modernas tienen todos un formato entero estándar, pero he oído que no todas usan el estándar IEEE para enteros de coma flotante. ¿Es esto cierto?¿Existen plataformas modernas con formatos de flotación que no sean IEEE C/C++?

Aunque ciertamente podría simplemente mostrarlo como una cadena de caracteres en cada paquete, igual tendría que convertir a un "formato conocido" de cada cliente, independientemente de la plataforma. La norma printf() y atod() sería inadecuada.

Tenga en cuenta que, debido a que este juego es un programa de software libre/de código abierto que se ejecutará en GNU/Linux, * BSD y Microsoft Windows, no puedo usar soluciones propietarias ni soluciones de plataforma única.

Saludos,
Patrick

Respuesta

4

Creo que es seguro asumir que cada plataforma tiene una implementación de la especificación IEE-754 en la que puede confiar, sin embargo, incluso si implementan la misma especificación, no hay garantía de que cada plataforma tenga exactamente la misma implementación, tiene los mismos indicadores de control de FP establecidos, realiza las mismas optimizaciones o implementa las mismas extensiones no estándar. Esto hace que el determinismo de coma flotante sea muy difícil de controlar y algo poco confiable de usar para este tipo de cosas (donde se comunicarán los valores de PF a través de la red).

Para obtener más información al respecto; leer http://gafferongames.com/networking-for-game-programmers/floating-point-determinism/

Otro problema para resolver es el manejo de clientes que no tienen una unidad de coma flotante; la mayoría de las veces serán CPU, consolas o dispositivos integrados de gama baja. Asegúrese de tener esto en cuenta si desea orientarlos. La emulación de FP se puede hacer, pero tiende a ser muy lenta en estos dispositivos, por lo que tendrá que acostumbrarse a hacer cálculos de punto fijo. Sin embargo, tenga en cuenta que redactar clases elaboradas para resumir los cálculos de puntos flotantes y puntos fijos en el mismo código suena como un plan; pero en la mayoría de los dispositivos no lo es. No le permite exprimir la máxima precisión y rendimiento cuando se trata de valores de puntos fijos.

Otro problema es manejar la endianidad de los valores de coma flotante porque no puede simplemente intercambiar bytes y apilar 'm en un registro de coma flotante otra vez (los bytes pueden tener un significado diferente, vea http://www.dmh2000.com/cpp/dswap.shtml sobre eso).

Mi consejo sería convertir los flotadores a valores intermedios de punto fijo, hacer una corrección endian si es necesario y transmitir eso. Además, no asuma que dos cálculos de coma flotante en diferentes máquinas producirán los mismos resultados; ellos no. Sin embargo, las implementaciones de punto flotante distintas de IEEE-754 son raras. Por ejemplo, las GPU tienden a usar punto fijo, pero es más probable que tengan un subconjunto de IEEE-754 en estos días porque no quieren lidiar con excepciones de división por cero, pero tendrán extensiones para flotantes que encajan en 16 bits

También tenga en cuenta que hay bibliotecas que ya han resuelto este problema (enviando formatos de datos de bajo nivel en un contexto de juego) por usted. Una de esas librerías es RakNet, específicamente su clase BitStream está diseñada para enviar estos tipos de datos de manera confiable a diferentes plataformas mientras se mantienen los gastos generales al mínimo; por ejemplo, RakNet tiene problemas para no desperdiciar ancho de banda al enviar cadenas o vectores.

+0

El vínculo de determinismo que me diste es muy interesante. Había estado pensando en hacer eso con algunos mensajes más grandes para asegurarme de que los clientes estuvieran sincronizados. Siempre que las posiciones estén lo suficientemente cerca (una unidad es un metro), creo que todo estará bien. No tengo la intención de apuntar a las plataformas de consola y a la mayoría de los sistemas integrados; Ni siquiera estoy seguro de si puedo hacer esto como Software Libre. En cuanto a los procesadores de gama baja, eso es más una preocupación. El problema del intercambio de bytes es muy desafortunado ... Describí brevemente el artículo, pero tendré que leerlo más tarde. ¡Muchas gracias por la información! –

+0

Hay algunas consolas (portátiles) menos conocidas que le permiten publicar software de código abierto para ellas, como GP2X y Open Pandora. El problema del determinismo de punto flotante aparece principalmente cuando se decide descentralizar las rutinas de física (por ejemplo, ejecutarlas en los clientes) o ejecutar repeticiones en máquinas diferentes porque tienden a acumular errores bastante rápido. –

1

Algunos procesadores embebidos no incluyen ningún tipo de hardware de punto flotante en absoluto. Para las computadoras de escritorio, no veo ninguna razón para preocuparme demasiado, aparte de los detalles que solo molestan realmente a los especialistas (sqrt) que se redondean incorrectamente en el Alpha, este tipo de cosas. Las diferencias que los molestan son en la implementación de las operaciones, no del formato, de todos modos).

Una variación entre plataformas está relacionada con el manejo de denormals. I asked a question about those a while back. Incluso eso no fue tan malo como esperaba.

+0

Muy bien, gracias Pascal. Definitivamente ayudará a no tener que preocuparse tanto por el formato binario de flotadores en el juego. Asumir flotadores IEEE-754 hace que mi vida sea mucho más fácil.^_^ –

6

Si abstrae correctamente su interfaz de red, puede tener funciones/objetos que serialicen y deserialicen los tipos de datos float. En todos los sistemas en los que puedo pensar, estos son los estándares IEEE, por lo que simplemente harían que pasen los datos sin cambios (el compilador probablemente incluso lo optimice, para que no pierda ningún rendimiento). Si encuentra algún sistema con un formato diferente, puede compilar de forma condicional en algún código de estas funciones para realizar modificaciones de bits para convertir el estándar IEEE al formato nativo. Solo necesitarás cambiarlo en un solo lugar. Sin embargo, probablemente nunca tenga que hacerlo, a menos que entre en consolas/dispositivos de bolsillo/etc.

+0

Así es como mi sistema está diseñado en este momento. No estaba seguro de lo común que es para un flotador que no sea IEEE. Seguiré tu consejo y lo guardaré. Gracias! –

Cuestiones relacionadas