Praktische SIMD-Mathematik für Spiele: Raytracer testet SSE-Leistung

Am 4. Mai 2013 veröffentlichte GameDev.net den zweiten Teil einer Reihe über portable SIMD-Mathematik. Im Mittelpunkt steht ein Raytracer, der Vektorrechnung unter realistischen Bedingungen testet und dabei Fehler in einer C++-Bibliothek sichtbar macht.

Die Reihe richtet sich an Entwickler, die mathematische Grundtypen für mehrere Prozessorarchitekturen kapseln. Der Artikel behandelt unter anderem SSE, MMX und die Benennung von Vektortypen für GCC und Clang. Die Beispiele stammen aus einer Spieleentwicklungsumgebung und bleiben bewusst näher an einem Testprogramm als an einer fertigen Rendering-Lösung.

Raytracing findet Fehler in der Vektorrechnung

Der Raytracer übernimmt die Rolle eines belastbaren Testfelds. Seine Berechnungen ähneln in Teilen der Mathematik eines Spiels, zugleich beansprucht er Speicher und Rechenwerk so stark, dass sich mehrere Minuten Spielberechnung in wenigen Sekunden prüfen lassen. Beim Test der Vector3fv-Klasse traten laut Artikel bereits in den ersten Stunden zahlreiche Fehler auf. Ein falscher versteckter Wert bei einer Skalarmultiplikation erzeugte etwa NaN-Werte, die spätere Rechnungen verfälschten.

Für die Prüfung von NaN und unendlichen Werten nutzt die Implementierung SIMD-Operationen, statt jedes einzelne Element aus einem Register zu holen. Eine zusätzliche Debugging-Option lässt sich über CMake aktivieren. Die ausführlichen Prüfungen verlangsamen die Mathematik im Beispiel allerdings um ungefähr 50 Prozent und sind deshalb vor allem für gezielte Tests gedacht. Vergleichbare Fragen zu Daten und Zuständen tauchen auch bei der Unity-Serialisierung auf.

SSE4 verkürzt die Laufzeit des Testprogramms

Für eine Szene mit Ebenen und Kugeln vergleicht der Autor vier Varianten. Die reine C++-Version benötigt 41,6 Sekunden, die Referenzimplementierung 47,4 Sekunden. Mit SSE sinkt die Laufzeit auf 36,3 Sekunden, mit SSE4 auf 33,0 Sekunden. Das entspricht gegenüber der reinen C++-Variante einem Vorteil von rund 15 beziehungsweise 26 Prozent. Die Messung bezieht sich auf einen Intel-Prozessor mit Microsoft Visual C++ und abgeschalteter automatischer SSE-Nutzung durch den Compiler.

Ein weiterer Test untersucht, wie die SIMD-Grundtypen an Funktionen übergeben werden. Werden Wrapper-Klassen zwischen nicht eingebundenen Funktionen kopiert, müssen Register unter Umständen in den Speicher geschrieben und anschließend erneut geladen werden. Die Übergabe der grundlegenden SIMD-Typen verbessert im Beispiel besonders die SSE4-Variante. Der Beitrag weist zugleich darauf hin, dass solche Detailoptimierungen erst nach der Prüfung des eigentlichen Algorithmus sinnvoll sind.

Weitere News

Weitere News

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein