Hintergrund
Ich habe in meiner Freizeit daran gearbeitet, eine Multithread-Spiel-Engine zu erstellen, und ich versuche derzeit, den besten Weg zu finden, um ein Entitätssystem in das zu integrieren, was ich bereits erstellt habe. Bisher habe ich diesen Artikel von Intel als Ausgangspunkt für meinen Motor verwendet. Bisher habe ich die normale Spielschleife mithilfe von Aufgaben implementiert und gehe nun dazu über, einige der Systeme und / oder Entitätssysteme zu integrieren. Ich habe in der Vergangenheit etwas Ähnliches wie Artemis verwendet , aber die Parallelität stört mich.
Der Artikel von Intel scheint zu befürworten, mehrere Kopien von Entitätsdaten zu haben und Änderungen an jeder Entität vorzunehmen, die am Ende eines vollständigen Updates intern verteilt werden. Dies bedeutet, dass das Rendern immer einen Frame hinter sich hat, aber dies scheint angesichts der Leistungsvorteile, die erzielt werden sollten, ein akzeptabler Kompromiss zu sein. Wenn es jedoch um ein Entitätssystem wie Artemis geht, bedeutet das Duplizieren jeder Entität für jedes System, dass jede Komponente auch dupliziert werden muss. Dies ist machbar, aber für mich scheint es, als würde es viel Speicher verbrauchen. Die Teile des Intel-Dokuments, die dies diskutieren, sind hauptsächlich 2.2 und 3.2.2. Ich habe einige Suchen durchgeführt, um zu sehen, ob ich gute Referenzen für die Integration der Architekturen finden konnte, die ich anstrebe, aber ich konnte noch nichts Nützliches finden.
Hinweis: Ich verwende C ++ 11 für dieses Projekt, aber ich stelle mir vor, dass das meiste, was ich frage, ziemlich sprachunabhängig sein sollte.
Mögliche Lösung
Verfügen Sie über einen globalen EntityManager, der zum Erstellen und Verwalten von Entities und EntityAttributes verwendet wird. Erlauben Sie Lesezugriff nur während der Aktualisierungsphase und speichern Sie alle Änderungen in einer Warteschlange pro Thread. Sobald alle Aufgaben abgeschlossen sind, werden die Warteschlangen kombiniert und die jeweiligen Änderungen übernommen. Dies hätte möglicherweise Probleme mit mehreren Schreibvorgängen in dieselben Felder, aber ich bin sicher, dass es ein Prioritätssystem oder einen Zeitstempel geben könnte, um dies zu klären. Dies scheint mir ein guter Ansatz zu sein, da Systeme in der Phase der Änderungsverteilung ganz natürlich über Änderungen an Entitäten informiert werden können.
Frage
Ich suche nach Feedback zu meiner Lösung, um zu sehen, ob sie überhaupt Sinn macht. Ich werde nicht lügen und behaupten, ein Experte für Multithreading zu sein, und ich mache dies größtenteils zum Üben. Ich kann einige komplizierte Probleme erkennen, die sich aus meiner Lösung ergeben, wenn mehrere Systeme mehrere Werte lesen / schreiben. Die von mir erwähnte Änderungswarteschlange kann auch schwer so zu formatieren sein, dass mögliche Änderungen leicht kommuniziert werden können, wenn ich nicht mit POD arbeite.
Jedes Feedback / Rat wäre sehr dankbar! Vielen Dank!
Links
- http://software.intel.com/en-us/articles/designing-the-framework-of-a-parallel-game-engine
- http://gamadu.com/artemis/
- http://www.gamedev.net/topic/560083-rendering-in-a-task-based-multithreaded-environment/ (in diesem Beitrag nicht erwähnt, aber ähnliche Lösung erwähnt)