Muss ich immer noch einen festen Punkt verwenden, um sicherzustellen, dass Computer für mathematische Operationen nicht mehr das gleiche Ergebnis erzielen?

9

Mir wurde gesagt, dass die meisten modernen Computer dem gleichen Gleitkomma-Standard folgen. Bedeutet dies, dass sie alle die gleiche Gleitkomma-Antwort für eine bestimmte mathematische Operation erhalten, wenn die Eingaben gleich sind?

Ich frage, weil ich nach einem RTS-Spiel in einem Netzwerk forsche und Hunderte von Einheitenpositionen synchronisieren, klingt nach einem schlechten Weg.

Wenn ich also nur Eingaben sende, muss ich garantieren, dass alle Clients das gleiche Ergebnis erzielen, indem sie die Simulation von diesen Eingaben aus ausführen.

Ich habe gelesen, dass ältere RTS-Spiele Festkomma-Arithmetik verwendeten, aber ich weiß nicht, ob dies auf modernen Computern noch erforderlich ist, wenn alle denselben Standard einhalten? Mir wurde auch gesagt, dass das Ergebnis des Gleitkommas zwar ungenau ist, aber für dieselbe Eingabe deterministisch ist (was vermutlich bedeutet, dass jeder Computer, der demselben Standard folgt, dasselbe ungenaue Ergebnis erhält?).

Haben Computer immer noch Abweichungen, auch wenn sie dem gleichen Gleitkomma-Standard folgen?

Ich schreibe dieses Spiel in C # und bin mir nicht sicher, ob das wichtig ist. Ich dachte, ich würde es trotzdem erwähnen.

WDUK
quelle
Selbst wenn sie es tun würden, würde ich keine Schwimmer dafür verwenden
Telastyn
Was meinen Sie ? Warum nicht?
WDUK
Die Verwendung von Floats kann ohnehin unerwünscht sein, da das Verhalten von der Position auf der Karte abhängen kann. Minecrafts Far Lands waren ein bemerkenswerteres Beispiel: Bewegung, Rendering und Geländegenerierung würden unangenehm, wenn Sie sich weit vom Spawnpunkt entfernt hätten.
Amon

Antworten:

18

Haben Computer immer noch Abweichungen, auch wenn sie dem gleichen Gleitkomma-Standard folgen?

Leider ja, besonders wenn Sie C # (oder eine andere JIT-kompilierte Sprache) verwenden. Das Problem, das hier auftritt, besteht darin, dass die JIT-Kompilierungsphase auf einigen Prozessorarchitekturen Code erzeugt, der mehr CPU-Register verwendet als auf anderen Architekturen. Dies kann zu Situationen führen, in denen auf einigen Maschinen für bestimmte Vorgänge eine erweiterte Gleitkommapräzision verwendet wird, auf anderen Maschinen jedoch nicht. Dies bedeutet, dass für jede iterative Berechnung mit Doppelwerten die Möglichkeit besteht, unterschiedliche akkumulierte Rundungsfehler zu erzeugen.

Das ist kein hypothetisches Problem, ich habe Erfahrungen aus erster Hand mit solchen Abweichungen in der modernen technischen Simulationssoftware auf mehr oder weniger moderner Hardware. Dieses Problem macht es wirklich schwierig, zuverlässige Regressionstests für komplexe Gleitkommaberechnungen zu erstellen, die auf allen beteiligten Maschinen genau das gleiche Ergebnis liefern.

Doc Brown
quelle
Diese. Einige Hauptursachen: IEEE Std 754 enthält optionale "Sollte" -Klauseln (z. B. NaN-Behandlung) und ermöglicht Entwurfsalternativen (z. B. Unterlauferkennung). Soweit Sprachbindungen den Gleitkomma-Standard unterstützen, können sie dem Compiler dennoch Spielraum bei der Auswertung von Gleitkommaausdrücken geben, z. B. FLT_EVAL_METHODin ISO C / C ++. Transzendente Funktionen (zB sin, exp, log) sind weitgehend sowohl von dem IEEE Floating-Point - Standard nicht geregelt und Sprachstandards zu programmieren. Ein einfaches Upgrade der Bibliotheksversion (z. B. eine neue glibcVersion) kann zu unterschiedlichen Ergebnissen führen.
Njuffa
Ich habe es selbst in einem Spiel getroffen. Die Rakete flog gut auf meinem Laptop, würde nicht auf meinem Desktop fliegen, völlig identische Installationen.
Loren Pechtel
3

Gleitkommafehler

Jede Gleitkommazahl akkumuliert Ungenauigkeiten, wenn sie zur Berechnung verwendet wird. Dies ist eine einfache Tatsache bei der Verwendung eines ungenauen Formats zum Berechnen. Die Berechnungen sind auch abhängig von der Reihenfolge der Berechnung. Die Kommutativität kann nicht garantiert werden, dh: (a + b) + ckann oder kann nicht dieselbe sein wie a + (b + c).

Außerdem haben Prozessoren nicht unbedingt die gleiche Mantissenlänge wie der Speicherstandard. Dies kann zu einem interessanten Verhalten führen, da der 32/64/128-Bit-Float gelegentlich so funktioniert, als ob er mehr Bits hätte.

Fixpunktfehler

Allerdings kann die Festkomma-Arithmetik auch Fehler akkumulieren. Der Unterschied besteht darin, dass Festkommazahlen klar sind, welche Genauigkeit verloren geht, und abhängig von den gewählten Operationen Rundungsfehler insgesamt vermeiden können. Sie sind auch kommutativ (a + b) + c = a + (b + c).

Welche?

Welche Sie verwenden möchten, hängt ganz davon ab, welche Eigenschaften Sie benötigen.

Gleitkommazahlen:

  • Geben Sie eine Vielzahl von Werten an, die aus der Nähe sehr feinkörnig werden und an den Extremen immer weiter auseinander liegen.
  • sind empfindlich gegenüber der Reihenfolge der Berechnung
  • Sammeln Sie mit der Zeit Rundungsfehler.
  • kann aufgrund einer Nichtübereinstimmung der Hardware- / Speicher-Float-Größe ein fehlerhaftes Verhalten aufweisen.

Festkommazahlen:

  • Geben Sie einen kleineren Zahlenbereich mit dem gleichen Abstand zwischen zwei aufeinander folgenden Zahlen an.
  • sind weniger empfindlich gegenüber der Reihenfolge der Berechnung
  • sind klarer über Rundungsfehler
  • kann bearbeitet werden, um Rundungsprobleme zu minimieren / zu vermeiden.
Kain0_0
quelle
1
"Festkommazahlen sind klar darüber, welche Präzision verloren geht" - Gleitkommazahlen sind ebenfalls klar, der Unterschied besteht eher darin, dass Ungenauigkeiten bei Festkommazahlen für die normale
Lebensnummerierung
1
Nur ein Fixpunkt garantiert also, dass alle Computer unabhängig von Hardware usw. die gleichen Fehler / Präzisionsverluste erleiden?
WDUK
1
Im Wesentlichen ja, da Sie angeben können, dass Ihre Festkommazahlen 32 oder 64 Bit sind und auf allen Systemen vorhanden sind. Gleitkommazahlen können 32 oder 64 Bit sein, aber die Hardware kann tatsächlich 48 oder 96 Bit verwenden, um die Berechnung durchzuführen und am Ende in 32 oder 64 Bit umzuwandeln, was zu Unterschieden zwischen verschiedenen Hardwaretypen führt.
user1118321
@whatsisname Obwohl die Gleitkomma-Spezifikationen ziemlich klar sind, können Sie mir nicht leicht sagen, auf welche Rundungsprobleme ich in dieser Summe stoßen werde : (a + b * c) / d - e. Mit Ausnahme offensichtlicher Probleme wie NaNDivision durch Null oder Überlauf / Unterlauf kann dieser Ausdruck falsch sein. Hinzu kommt, dass die Impedanz zwischen Speicher und Register in Bezug auf die Genauigkeit und sogar ein einfaches Laden / Speichern aus dem Speicher mit dem "gleichen" Gleitkommawert die Antwort ändert.
Kain0_0
@ Kain0_0: Du hast recht, ich kann dir nicht leicht sagen, was mir begegnen wird, weil ich kein Gleitkomma-Experte bin. Genau das ist gemeint, als ich sagte "intuitiver zur normalen Lebensnummerierung". Wenn Sie sagen, dass der Fixpunkt "klar" ist und der Gleitkomma nicht, klingen Sie so, als wären Gleitkommazahlen nur scheinbar zufällig ungenau.
Whatsisname
-1

Es stellt sich die Frage, warum Sie identische Ergebnisse garantieren möchten, da identische Ergebnisse überhaupt keine Garantie dafür geben, dass Ihre Ergebnisse nützlich sind .

Sie könnten einen numerisch instabilen Algorithmus haben, der auf verschiedenen Computern zwei identische, aber völlig unsinnige Ergebnisse liefert. Wenn es Unterschiede gibt, die Ergebnisse jedoch innerhalb von 13 Stellen gleich sind, ist dies viel vertrauenswürdiger.

Es gibt nur sehr wenige Situationen, in denen die Reproduzierbarkeit wirklich wichtig ist: in einer Layout-Engine oder verlustfreie Komprimierung / Dekomprimierung. Die Verwendung von Festpunkten ist sehr wahrscheinlich falsch.

gnasher729
quelle
Ich habe Ihre Antwort nicht abgelehnt, aber es scheint, dass der vom OP beschriebene Fall genau "eine der wenigen Situationen ist, in denen die Reproduzierbarkeit wirklich wichtig ist". In einem RTS-Spiel kann ein kleiner Rundungsfehler den Unterschied zwischen "zwei kollidierten Objekten" ausmachen oder nicht.
Doc Brown