Dois-je toujours utiliser un point fixe pour garantir que les ordinateurs obtiennent le même résultat pour les opérations mathématiques?

9

On m'a dit que la plupart des ordinateurs modernes suivent la même norme à virgule flottante, cela signifie-t-il qu'ils obtiendront tous la même réponse flottante pour une opération mathématique donnée si les entrées sont les mêmes?

Je demande parce que je fais des recherches sur la création d'un jeu RTS sur un réseau et que la synchronisation de centaines de positions d'unité semble être une mauvaise façon de procéder.

Donc, si j'envoie uniquement des entrées, je dois garantir que tous les clients obtiennent le même résultat en les faisant exécuter la simulation à partir de ces entrées.

J'ai lu que les anciens jeux RTS utilisaient l'arithmétique à virgule fixe, mais je ne sais pas si cela est toujours requis sur les ordinateurs modernes s'ils adhèrent tous à la même norme? On m'a également dit que bien qu'imprécis, le résultat de la virgule flottante est déterministe pour la même entrée (ce qui, je suppose, signifie que tout ordinateur suivant la même norme obtient le même résultat imprécis?).

Les ordinateurs ont-ils encore des écarts même s'ils suivent la même norme de point flottant?

J'écris ce jeu en C #, je ne sais pas si cela importe, pensais que je le mentionnerais de toute façon.

WDUK
la source
Même s'ils le faisaient, je n'utiliserais pas de flotteurs pour cela
Telastyn
Que voulez-vous dire ? Pourquoi pas?
WDUK
L'utilisation de flotteurs peut de toute façon être indésirable car le comportement peut dépendre de la position sur la carte. Les Terres lointaines de Minecraft en étaient un exemple plus notable: le mouvement, le rendu et la génération de terrain deviendraient glitch lorsque vous vous éloigniez du point d'apparition.
amon

Réponses:

18

Les ordinateurs ont-ils encore des écarts même s'ils suivent la même norme de point flottant?

Malheureusement, oui, surtout lorsque vous utilisez C # (ou un autre langage compilé JIT). Le problème qui se produit ici est que l'étape de compilation JIT sur certaines architectures de processeur produit du code qui utilise plus de registres CPU que sur d'autres architectures. Cela peut conduire à des situations où sur certaines machines, une précision en virgule flottante étendue est utilisée pour certaines opérations, tandis que sur d'autres machines non. Cela signifie que pour chaque calcul itératif utilisant des doubles, il est possible de produire différentes erreurs d'arrondi cumulées.

Ce n'est pas un problème hypothétique, j'ai une expérience de première main avec de telles déviations dans les logiciels de simulation d'ingénierie contemporaine, sur du matériel plus ou moins moderne. Ce problème rend très difficile la création de tests de régression fiables pour des calculs complexes en virgule flottante qui produisent exactement le même résultat sur toutes les machines impliquées.

Doc Brown
la source
Cette. Quelques causes profondes: IEEE Std 754 inclut des clauses facultatives "devrait" (par exemple la gestion de NaN) et permet des alternatives de conception (par exemple la détection de sous-dépassement). Dans la mesure où les liaisons de langage prennent en charge la norme à virgule flottante, elles peuvent toujours donner une marge de manœuvre au compilateur lors de l'évaluation des expressions à virgule flottante, par exemple FLT_EVAL_METHODen ISO C / C ++. Fonctions transcendantes (par exemple sin, exp, log) ne sont pas réglementés à la fois par les normes linguistiques standard et la programmation à virgule flottante IEEE. Une simple mise à niveau de la version de la bibliothèque (par exemple une nouvelle glibcversion) peut entraîner des résultats différents.
njuffa
Je l'ai touché moi-même dans un match. La fusée a bien volé sur mon ordinateur portable, ne volerait pas sur mon bureau, des installations complètement identiques.
Loren Pechtel
3

Erreurs en virgule flottante

Chaque nombre à virgule flottante accumule l'imprécision lorsqu'il est utilisé pour le calcul. Il s'agit d'un simple fait d'utiliser un format imprécis pour calculer. Les calculs sont également sensibles à l'ordre de calcul, la commutativité n'est pas garantie, c'est-à-dire: (a + b) + cpeut ou peut ne pas être identique à a + (b + c).

De plus, les processeurs n'ont pas nécessairement la même longueur de mantisse que le standard de mémoire. Cela peut générer un comportement intéressant car le flotteur 32/64/128 bits fonctionne parfois comme s'il avait plus de bits.

Erreurs à virgule fixe

Cela étant dit, l'arithmétique à virgule fixe peut également accumuler des erreurs. La différence est que les nombres à virgule fixe indiquent clairement quelle précision est perdue et, en fonction des opérations choisies, peuvent éviter complètement les erreurs d'arrondi. Ils sont également commutatifs (a + b) + c = a + (b + c).

Lequel?

Laquelle utiliser dépend entièrement des propriétés dont vous avez besoin.

Nombres à virgule flottante:

  • donnent une vaste gamme de valeurs qui deviennent de plus en plus à grain très fin et progressivement plus éloignées aux extrémités.
  • sont sensibles à l'ordre de calcul
  • accumuler les erreurs d'arrondi au fil du temps.
  • peut avoir un comportement erratique en raison de l'inadéquation de la taille du flotteur matériel / mémoire.

Numéros de points fixes:

  • donne une plus petite plage de nombres avec la même distance entre deux nombres consécutifs.
  • sont moins sensibles à l'ordre de calcul
  • sont plus clairs sur les erreurs d'arrondi
  • peut être utilisé pour minimiser / éviter les problèmes d'arrondi.
Kain0_0
la source
1
"les nombres à virgule fixe sont clairs sur la précision perdue" - les virgules flottantes sont claires aussi, la différence est que les inexactitudes des
virgules
1
Donc, seul le point fixe garantit que tous les ordinateurs, indépendamment du matériel, etc., subiront les mêmes erreurs / pertes de précision?
WDUK
1
Essentiellement, oui, car vous pouvez spécifier que vos nombres à virgule fixe sont 32 ou 64 bits, et ils seront sur tous les systèmes. Les nombres à virgule flottante peuvent être de 32 ou 64 bits, mais le matériel peut en fait utiliser 48 ou 96 bits pour effectuer le calcul et se convertir à 32 ou 64 bits à la fin, ce qui entraîne des différences entre les différents types de matériel.
user1118321
@whatsisname Bien que les spécifications en virgule flottante sont tout à fait clair, vous ne pouvez pas me dire facilement ce que les questions que je vais rencontrer l' arrondissement dans cette somme: (a + b * c) / d - e. À l'exception de problèmes évidents tels que la NaNdivision par zéro ou le dépassement / dépassement, il est possible que cette expression soit incorrecte. Ajoutez à cela l'impédance entre la mémoire et le registre en termes de précision et même un simple chargement / stockage à partir de la mémoire de la "même" valeur à virgule flottante changera la réponse.
Kain0_0
@ Kain0_0: vous avez raison, je ne peux pas facilement vous dire ce que je vais rencontrer, car je ne suis pas un expert en virgule flottante. C'est exactement ce que l'on entend quand je dis "numérotation plus intuitive à la vie ordinaire". Lorsque vous dites que le point fixe est "clair" et que le point flottant ne l'est pas, vous donnez l'impression que les flottants sont tout simplement inexacts au hasard.
whatsisname
-1

Il y a la question de savoir pourquoi vous voudriez garantir des résultats identiques, car des résultats identiques ne donnent aucune garantie que vos résultats sont utiles .

Vous pourriez avoir un algorithme numériquement instable qui donne deux résultats identiques mais complètement absurdes sur différents ordinateurs. S'il y a des différences, mais que les résultats sont les mêmes à 13 chiffres, c'est beaucoup plus fiable.

Il y a très peu de situations où la reproductibilité est vraiment importante: dans un moteur de mise en page, ou compression / décompression sans perte. L'utilisation d'un point fixe risque fort d'être erronée.

gnasher729
la source
Je n'ai pas déçu votre réponse, mais il semble que le cas décrit par le PO soit exactement "l'une de ces rares situations où la reproductibilité est vraiment importante". Dans un jeu RTS, une petite erreur d'arrondi peut faire la différence entre «deux objets entrés en collision» ou non.
Doc Brown