2010-04-27 11 views
8

J'écris un jeu vidéo, Humm and Strumm, qui nécessite un composant réseau dans son moteur de jeu. Je peux facilement faire face aux différences dans l'endianness, mais j'ai frappé un mur en essayant de traiter des formats de mémoire possibles. Je sais que les ordinateurs modernes ont tous un format entier standard, mais j'ai entendu dire qu'ils ne peuvent pas tous utiliser la norme IEEE pour les entiers à virgule flottante. Est-ce vrai?Existe-t-il des plates-formes modernes avec des formats flottants non IEEE C/C++?

Bien que je puisse certainement le sortir comme une chaîne de caractères dans chaque paquet, je devrais encore convertir à un "format bien connu" de chaque client, indépendamment de la plate-forme. La norme printf() et atod() serait inadéquate. Veuillez noter que ce jeu étant un logiciel libre/Open Source fonctionnant sous GNU/Linux, * BSD et Microsoft Windows, je ne peux utiliser aucune solution propriétaire ni aucune solution à plateforme unique.

Cheers,
Patrick

Répondre

4

Je pense qu'il est raisonnable de supposer que chaque plate-forme a une implémentation de la spécification IEE-754 sur laquelle vous pouvez compter, cependant, même si tous implémenter la même spécification, il n'y a aucune garantie que chaque plate-forme implémentation, les mêmes indicateurs de contrôle FP sont définis, effectue les mêmes optimisations ou implémente les mêmes extensions non standard. Cela rend le déterminisme à virgule flottante très difficile à contrôler et peu fiable à utiliser pour ce genre de chose (où vous communiquerez des valeurs FP sur le réseau).

Pour plus d'informations à ce sujet; lire http://gafferongames.com/networking-for-game-programmers/floating-point-determinism/

Un autre problème à résoudre est de gérer les clients qui n'ont pas d'unité à virgule flottante; la plupart du temps, il s'agira de processeurs, de consoles ou de périphériques embarqués de bas de gamme. Assurez-vous de prendre cela en compte si vous voulez les cibler. L'émulation de FP peut être faite, mais elle a tendance à être très lente sur ces périphériques. Vous devrez donc faire des calculs à virgule fixe. Soyez avisé cependant, écrire des classes élaborées pour résumer des calculs à virgule flottante et à virgule fixe au même code ressemble à un plan; mais sur la plupart des appareils ne l'est pas. Cela ne vous permet pas d'extraire la précision et les performances maximales lorsque vous traitez des valeurs de points fixes.Un autre problème est de gérer l'endianness des valeurs à virgule flottante car vous ne pouvez pas simplement échanger des octets et les empiler dans un registre flottant (les octets peuvent avoir une signification différente, voir http://www.dmh2000.com/cpp/dswap.shtml).

Mon conseil serait de convertir les flottants en valeurs intermédiaires à virgule fixe, de faire une correction d'endian si nécessaire et de transmettre cela. En outre, ne supposez pas que deux calculs à virgule flottante sur des machines différentes donneront les mêmes résultats; ils ne le font pas. Cependant, les implémentations en virgule flottante autres que IEEE-754 sont rares. Par exemple, les GPU ont tendance à utiliser un point fixe, mais sont plus susceptibles d'avoir un sous-ensemble de IEEE-754 ces jours-ci parce qu'ils ne veulent pas gérer les exceptions de division par zéro, mais ils auront des extensions pour les demi-flottants 16 bits.

Sachez également qu'il existe des bibliothèques qui ont déjà résolu ce problème (envoi de formats de données de bas niveau dans un contexte de jeu) pour vous. Une telle bibliothèque est RakNet, en particulier sa classe BitStream est conçue pour envoyer ces types de données de manière fiable à différentes plates-formes tout en réduisant au minimum les frais généraux; Par exemple, RakNet a beaucoup de mal à ne pas perdre de bande passante lors de l'envoi de chaînes ou de vecteurs.

+0

Le lien déterminisme que vous m'avez donné est très intéressant. J'avais pensé faire cela avec des messages plus importants pour m'assurer que les clients étaient synchronisés. Tant que les positions sont assez proches (une unité fait un mètre), je pense que ça ira. Je n'ai pas l'intention de cibler les plates-formes de console et la plupart des systèmes embarqués; Je ne suis même pas sûr si je peux le faire en tant que logiciel libre. En ce qui concerne les processeurs bas de gamme, cela est plus préoccupant. Le problème de l'échange d'octets est très regrettable ... J'ai brièvement parcouru l'article, mais je devrai le lire plus tard. Merci beaucoup pour l'information! –

+0

Il existe des consoles moins connues (portables) qui vous permettent de publier des logiciels open source comme GP2X et Open Pandora. Le problème du déterminisme en virgule flottante survient principalement lorsque vous décidez de décentraliser les routines de physique (par exemple, les exécuter sur les clients) ou d'exécuter des replays sur des machines différentes car elles ont tendance à accumuler des erreurs assez rapidement. –

1

Certains processeurs embarqués ne comprennent pas de matériel à virgule flottante du tout. Pour les ordinateurs de bureau, je ne vois pas de raison de m'inquiéter trop, à part les détails qui ne font que gêner les spécialistes (sqrt étant incorrectement arrondi sur l'Alpha, ce genre de chose.) Les différences qui les gênent sont dans l'implémentation des opérations, pas du format, de toute façon).

Une variation entre les plates-formes est liée à la gestion de dénormaux. I asked a question about those a while back. Même ce n'était pas aussi mauvais que prévu.

+0

Très bien, merci Pascal. Il sera certainement utile de ne pas avoir à se soucier autant du format binaire des flotteurs dans le jeu. En supposant que les flotteurs IEEE-754 rendent ma vie beaucoup plus facile.^_^ –

6

Si vous abstractionz correctement votre interface réseau, vous pouvez avoir des fonctions/objets qui sérialisent et désérialisent les types de données flottants. Sur tous les systèmes auxquels je peux penser, il s'agit de la norme IEEE, de sorte que vous devez simplement leur faire passer les données sans les modifier (le compilateur optimisera probablement ces données, afin de ne perdre aucune performance). Si vous rencontrez un système avec un format différent, vous pouvez conditionnellement compiler dans du code dans ces fonctions pour faire des hacks bit à convertir de la norme IEEE au format natif. Vous aurez seulement besoin de le changer en un seul endroit. Cependant, vous n'aurez probablement jamais besoin de le faire, sauf si vous vous trouvez dans des consoles/ordinateurs de poche/etc.

+0

Voici comment mon système est conçu pour le moment. Je n'étais pas sûr à quel point il est commun pour un flotteur non IEEE. Je vais suivre votre conseil et le garder. Merci! –