Float, Double oder beides für die 2D-Vektorklasse?


11

Derzeit schreibe ich eine kleine plattformübergreifende OpenGL-basierte 2D-Game-Engine für unser Studio. Als ich nachforschte, welche 2D-Vektorklasse ich verwenden sollte, stieß ich auf drei verschiedene Designparadigmen:

  • Float & Call-by-Value, wie in diesem Gamasutra-Artikel . Scheint schnell zu sein, bietet aber wenig Präzision (siehe auch diesen Thread ). Pro: Schnell, portabel und kompatibel mit den meisten Bibliotheken.

  • Double & Call-by-Reference. Wenn ich den obigen Artikel richtig verstehe, könnte ich auch 2 Variablen mit doppelter Genauigkeit anstelle der 4 Gleitkommazahlen verwenden. Nach obigem Thread ist Double immer noch langsamer als Float.

  • Vorlage für Double und Float: Das weit verbreitete Buch " Game Engine Architecture " verwendet Vorlagen, um die Verwendung von Float und Double nach Bedarf zu ermöglichen. Der offensichtliche Nachteil ist das Aufblähen des Codes. Ich bezweifle auch, dass der Code optimiert werden kann, ohne grundsätzlich zwei Klassen zu schreiben.

Ich würde gerne erfahren, welche Lösungen Sie in Ihren internen Engines verwenden und wie präzise zB beliebte Game-Engines sind, damit ich entscheiden kann, welche Lösung ich in unserer Engine implementieren werde. Im Moment denke ich darüber nach, einfach Float-Präzision zu verwenden und damit zu leben.


Langsamer wo ? Sie können nicht über Geschwindigkeit sprechen, wenn dies nicht an eine bestimmte Architektur gebunden ist.
o0 '.

2
@ Lo'oris: Ich kenne keine Architektur, in der double schneller ist als float.

Anstatt Ihre eigene Vektorklasse zu schreiben, sollten Sie die von Sony verwenden ( bullphysics.org/Bullet/phpBB3/… ). Es handelt sich um eine einfache Drop-In-Header-Bibliothek, die bereits mikrooptimiert wurde, und alle Vektorbibliotheken sind ohnehin die gleiche externe Schnittstelle.

@ Joe: 2 Doppel statt 4 Floats?
o0 '.

@ Lo'oris: Die Frage ist etwas komisch formuliert, ich weiß nicht, ob der Fragesteller verwirrt ist oder nur Sie - Sie verwenden beim Umgang mit SIMD zwei doppelte "anstelle von" vier Floats, da das Register 128 Bit breit ist. Sie müssen immer noch die gleiche Anzahl von Zahlen verarbeiten, und das mit halber Geschwindigkeit.

Antworten:


9

Ich verwende immer float, es sei denn, ich habe einen Grund, double zu verwenden, genauso wie ich int verwende, es sei denn, ich habe einen Grund, int64_t zu verwenden.

Floats haben kein Problem damit, präzise Ganzzahlarithmetik bis zu 2 24 durchzuführen , wovor die meisten Menschen (meistens irrational) Angst haben. Doppelte Probleme lösen nicht das Problem, dass allgemeine Werte nicht genau darstellbar sind. Unabhängig davon, ob Sie 0,10000001 oder 0,10000000000000001 erhalten, müssen Sie dennoch sicherstellen, dass Ihr Code sie als "gleich" mit 0,09999999 betrachtet.

Doppel sind auf jeder Plattform, auf der Sie Spiele schreiben möchten, langsamer, benötigen die doppelte Speicherbandbreite und verfügen über weniger spezielle CPU-Anweisungen.

Floats mit einfacher Genauigkeit bleiben der Standard für Hardware-Grafikschnittstellen, sowohl auf der C / C ++ - Seite als auch innerhalb von Shadern.

Sie werden wahrscheinlich irgendwann einen Doppelvektor benötigen, der jedoch bei Bedarf verwendet werden sollte, nicht standardmäßig.

Was das Template betrifft - Sie haben Recht, für maximale Leistung möchten Sie die Vorlagen ohnehin manuell spezialisieren. Abgesehen davon habe ich am Wochenende einige Tests für Vorlagencode durchgeführt (Erstellen eines 4-Ple-IntRect und eines FloatRect) und festgestellt, dass das Kompilieren der Vorlagenversion etwa 20-mal länger dauerte als das Wiederholen des Codes, der sich auf etwa 15 Zeilen belief . Wiederholung ist scheiße, aber das Warten auf Kompilierungen ist scheiße - und es ist nicht so, dass ich jemals einen StringRect oder FooRect brauchen werde.


" Doppel sind auf jeder Plattform langsamer […] " - Zitieren erforderlich.
Zenit

3

Das Microsoft XNA-Spielframework verfügt über eine Vector2-Klasse, die Floats verwendet. Dies wäre mein größter persönlicher Grund für Floats, da ich darauf vertraue, dass die Weisheit und Erfahrung des XNA-Teams viel größer ist als meine eigene.

Ich fand es ziemlich interessant, die Antwort in dieser Frage zum Stapelüberlauf zu lesen: "Float vs Double Performance" . Es gibt auch einen gamedev.net-Thread mit einigen Erläuterungen zur doppelten Leistung in GPUs. Ich denke, man kann davon ausgehen, dass Doubles langsamer sind als Floats, zumindest in vielen GPUs, und ich persönlich habe die Float-OpenGL-Funktionen immer gegenüber ihren Double-Gegenstücken verwendet. Dies gilt heutzutage möglicherweise nicht mehr, aber wenn Sie bedenken, dass nicht jeder, der Ihr Spiel ausführt, über die neueste GPU mit nativer Doppelunterstützung verfügt, ist dies meiner Meinung nach Grund genug, Floats zu verwenden und ein bisschen mehr Leistung zu erzielen.


1
Aus der SO-Frage: "Auf x86-Prozessoren werden Float und Double von der FPU zur Verarbeitung jeweils in ein 10-Byte-Real konvertiert." Dies ist zwar richtig, vernachlässigt jedoch sowohl SIMD-Anweisungen als auch die zusätzlichen Speicheranforderungen (= schlechtere Cache-Kohärenz, mehr Speicherbandbreite) von Doubles, die beide in realen Tests weiterhin langsamer als Float machen.

Ich dachte, es gibt einen Haken. Sie sollten das zu der SO-Antwort kommentieren, ich würde es positiv bewerten.
Ricket

Es ist schon als Kommentar da.

1
Da Sie XNA aufgerufen haben, kann ich auch darauf hinweisen, dass Direct2D auch Floats mit einfacher Genauigkeit verwendet.
Mike Strobel

Der Vollständigkeit halber verfügt OpenGL über Float- und Double-Versionen seiner Methoden, sodass es in diesem Sinne neutral ist.
Ricket
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.