Wie weise ist diese Multithreading-Architektur?

7

Ich schreibe eine Spiel-Engine neu, die ich geschrieben habe, um so viel wie möglich zu parallelisieren. Ich denke darüber nach, Eigenschaften zu erstellen, auf die von mehreren Threads aus zugegriffen werden kann. Alle verwenden Accessoren, die boost scoped_locks verwenden, um Race-Bedingungen zu vermeiden.

Angenommen, ich habe einen Charakter mit der Basisklasse CharacterBase. Die X / Y / Z-Koordinaten des Charakters werden durch Accessoren mit Sperren mit Gültigkeitsbereich gesteuert. In der Hauptschleife werden 3 Threads ausgeführt, einer zum Verarbeiten der Physik, einer zum Verarbeiten des Renderns und einer zum Verarbeiten von Benutzereingaben usw.

Dies führt dazu, dass scoped_locks grundsätzlich überall vorhanden sind und vom Design explizit benötigt werden, wenn Benutzer die Engine erweitern. Ich habe vor, diese Open Source-Version zu erstellen, daher frage ich mich, ob dieses Design aus technischer Sicht oder aus Sicht des Endbenutzers (für diejenigen, die den Motor erweitern) erhebliche Mängel oder Nachteile aufweist. Vielen Dank!


quelle
2
Boreals Antwort war richtig. Versuchen Sie diese Links für weitere Forschungsinformationen. gamedev.stackexchange.com/questions/2116/…
Sean Middleditch

Antworten:

15

Sie schlagen vor, jedes einzelne "System" parallel auszuführen. Das Problem dabei ist, dass Sie jeden einzelnen gemeinsam genutzten Status sperren müssen. CLARITY EDIT: Wenn Sie zwei parallele Vorgänge mit denselben Daten ausführen, werden Sperrenkonflikte und Synchronisierungen die Dinge verlangsamen, sodass Sie nicht viele Vorteile aus der Parallelisierung ziehen.

Der Schlüssel zum Multithreading einer Spiel-Engine besteht darin, zu erkennen, dass viele Systeme SIMD-ähnliche Operationen ausführen, bei denen eine einzelne Operation über eine große Anzahl von Spielobjekten ausgeführt wird. Ein Beispiel ist das Hinzufügen der Beschleunigung jedes Objekts zu seiner Geschwindigkeit und das Hinzufügen seiner Geschwindigkeit zu seiner Position. Wenn so etwas passiert, können Sie die Arbeitslast auf mehrere Threads verteilen. Sie werden enorme Leistungssteigerungen feststellen, wenn Sie CPU-intensive Vorgänge wie Pfadfindung oder Kollisionsprüfung parallelisieren.

Dies ist besser, da der Spielstatus nicht gesperrt werden muss und keine Probleme im Zusammenhang mit der Synchronisierung oder dem Rennen auftreten. Tatsächlich muss sich Ihre Hauptschleife überhaupt nicht ändern!

jmegaffin
quelle
4
+1 Zusammenfassend also nicht sehr weise. Dies wird sicherlich die Rennbedingungen vermeiden, aber dies ist ein Weg zu schlechter Leistung und schlechteren, toten Schlössern. Ideales Multithreading ist sperrfrei.
Laurent Couvidou
1
Im Idealfall ja. Hier und da ein paar Variablen zu teilen ist in Ordnung, aber wenn Sie alles sperren müssen, woran Sie arbeiten, kann sowieso nichts parallel laufen.
Jmegaffin
Als korrekt markiert, obwohl ich einige Ressourcen gefunden habe, die darauf hindeuten, dass die Antwort subjektiv ist. preshing.com/20111118/locks-arent-slow-lock-contention-is . Wie auch immer, ich versuche nicht, argumentativ zu sein. Ich stimme Ihrer Antwort jetzt darin zu, dass dies nicht der idealste Ansatz ist. Danke fürs Schreiben!
1
Vielleicht war ich nicht klar genug. Wenn Sie zwei parallele Vorgänge mit denselben Daten ausführen, werden Sperrenkonflikte und Synchronisierungen die Dinge verlangsamen, sodass Sie nicht viele Vorteile aus der Parallelisierung ziehen. Sehr interessanter Artikel.
Jmegaffin
Nein, ich habe verstanden, dass ich nur gesagt habe, dass anhand der Benchmarks in dem Artikel, auf den verwiesen wird, selbst eine relativ hohe Anzahl von Sperren (320.000 pro Sekunde) zeigte, dass es immer noch einen 1,5-fachen Leistungsgewinn gegenüber der Single-Threaded-Version gibt. Es hängt davon ab, wie lange Sperren usw. gehalten werden. Aber im Allgemeinen und wie ich meine ursprüngliche Frage gestellt habe, stimme ich Ihrer Antwort zu, dass die Leistung im Allgemeinen negativ beeinflusst wird.