Sind Gleitkommaoperationen in Delphi deterministisch?

8

Sind Gleitkommaoperationen in Delphi deterministisch?

I.E. bekomme ich das gleiche Ergebnis von einer identischen mathematischen Gleitkommaoperation auf derselben ausführbaren Datei, die mit dem Delphi Win32 Compiler kompiliert wurde, wie mit dem Win64 Compiler oder dem OS X Compiler oder dem iOS Compiler oder dem Android Compiler?

Dies ist eine entscheidende Frage, da ich die Multiplayer-Unterstützung in meiner Spielengine implementiere, und ich befürchte, dass die Vorhersageergebnisse auf der Client-Seite sehr oft von der definitiven (und autoritativen) Bestimmung des Servers abweichen können / p>

Die Folge davon wäre das Auftreten von "Verzögerung" oder "Ruckeln" auf der Clientseite, wenn die autoritativen Spielzustandsdaten den prädiktiven Zustand auf der Clientseite überschreiben.

Da ich realistischerweise nicht in der Lage bin, Dutzende verschiedener Geräte auf verschiedenen Plattformen zu testen, die mit den verschiedenen Compilern in einem "kontrollierten Zustand" kompiliert sind, denke ich, dass es am besten ist, diese Frage den Delphi-Entwicklern zu stellen sehen Sie, ob jemand ein internes Verständnis des Fließkommadeterminismus auf einer niedrigen Ebene in den Compilern hat.

    
LaKraven 22.06.2014, 14:08
quelle

3 Antworten

6

Ich denke, es gibt keine einfache Antwort. Ähnliche Aufgabe wurde diskutiert hier . Im Allgemeinen gibt es zwei Standards für die Darstellung von Gleitkommazahlen: IEEE 754-1985 und EEE 754-2008. Alle modernen (und ziemlich alten) CPUs folgen den Standards und garantieren einige Dinge:

  • Binäre Darstellung des gleichen Standard-Floating-Typs ist gleich
  • Das Ergebnis einiger Operationen (nicht alle, nur einfache Operationen!) ist garantiert gleich, aber nur wenn der Compiler den gleichen Befehlstyp verwendet, bin ich mir nicht sicher, ob es wahr ist.

Wenn Sie jedoch einige erweiterte Operationen wie die Quadratwurzel verwenden, kann das Ergebnis selbst bei verschiedenen Modellen von Desktop-CPUs variieren. Sie können diesen Artikel für einige Details lesen: Ссылка

P.S. Wie tmyklebu erwähnt, ist die Quadratwurzel auch durch IEEE 754 definiert, so dass dasselbe Ergebnis für die gleiche Eingabe für Addieren, Subtrahieren, Multiplizieren, Dividieren und Quadratwurzel garantiert werden kann. Wenige andere Operationen werden ebenfalls von IEEE definiert, aber für alle Details ist es besser, IEEE zu lesen.

    
Andrei Galatyn 22.06.2014, 14:38
quelle
1

Bedenken Sie, dass die 32- und 64-Bit-Compiler kompilieren, um die alten FPUs gegen die neueren SSE-Anweisungen zu verwenden. Ich würde es schwierig finden, darauf zu vertrauen, dass jede Berechnung bei verschiedenen Hardwareimplementierungen immer genau gleich herauskommt. Gehen Sie besser den sicheren Weg und nehmen Sie an, dass wenn Sie innerhalb einer kleinen Delta-PF-Differenz sind, Sie als gleich auswerten.

    
NexusDB Expert 24.06.2014 01:59
quelle
1

Aus Erfahrung kann ich sagen, dass die Ergebnisse unterschiedlich sind: 32-Bit arbeitet standardmäßig mit der erweiterten Genauigkeit, während 64-Bit standardmäßig mit doppelter Genauigkeit arbeitet.

Betrachten Sie die Aussage

x, y, z: doppelt; x: = y * z;

in Win32 wird dies ausgeführt als "x: = double (Extended (y) * Extended (z)); in Win64 wird dies als "x: = double (double (y) * double (z))" ausgeführt;

Sie haben viel Mühe darauf verwendet, sicherzustellen, dass Sie dieselbe Präzision und denselben Modus verwenden. Wenn Sie jedoch Bibliotheken von Drittanbietern aufrufen, müssen Sie berücksichtigen, dass sie diese Flags intern ändern können.

    
Daniel 24.06.2014 15:07
quelle