Ich habe diesen Artikel gelesen und dieser Typ spricht weiter darüber, wie jeder davon profitieren kann, datenorientiertes Design mit OOP zu mischen. Er zeigt jedoch keine Codebeispiele.
Ich habe dies gegoogelt und konnte keine wirklichen Informationen darüber finden, geschweige denn Codebeispiele. Ist jemand mit diesem Begriff vertraut und kann ein Beispiel geben? Ist das vielleicht ein anderes Wort für etwas anderes?
data-oriented-design
Ryeguy
quelle
quelle
Antworten:
Verwechseln Sie dies zunächst nicht mit datengesteuertem Design.
Mein Verständnis von datenorientiertem Design ist, dass es darum geht, Ihre Daten für eine effiziente Verarbeitung zu organisieren. Insbesondere in Bezug auf Cache-Fehler usw. Bei Data Driven Design geht es dagegen darum, dass Daten einen Großteil Ihres Programmverhaltens steuern (sehr gut beschrieben durch Andrew Keiths Antwort ).
Angenommen, Ihre Anwendung enthält Kugelobjekte mit Eigenschaften wie Farbe, Radius, Sprungkraft, Position usw.
Objektorientierter Ansatz
In OOP würden Sie Bälle wie folgt beschreiben:
Und dann würden Sie eine Sammlung solcher Bälle erstellen:
Datenorientierter Ansatz
In Data Oriented Design schreiben Sie den Code jedoch eher wie folgt:
Wie Sie sehen, gibt es keine Einheit mehr, die einen Ball darstellt. Ballobjekte existieren nur implizit.
Dies kann in Bezug auf die Leistung viele Vorteile haben. Normalerweise möchten wir viele Bälle gleichzeitig operieren. Hardware möchte normalerweise, dass große, kontinuierliche Speicherblöcke effizient arbeiten.
Zweitens können Sie Operationen ausführen, die nur einen Teil der Eigenschaften eines Balls betreffen. Wenn Sie beispielsweise die Farben aller Kugeln auf verschiedene Weise kombinieren, soll Ihr Cache nur Farbinformationen enthalten. Wenn jedoch alle Ball-Eigenschaften in einer Einheit gespeichert sind, ziehen Sie auch alle anderen Eigenschaften eines Balls ein. Auch wenn du sie nicht brauchst.
Cache-Verwendungsbeispiel
Angenommen, jeder Ball benötigt 64 Bytes und ein Punkt 4 Bytes. Ein Cache-Slot benötigt beispielsweise auch 64 Bytes. Wenn ich die Position von 10 Bällen aktualisieren möchte, muss ich 10 * 64 = 640 Bytes Speicher in den Cache ziehen und 10 Cache-Fehler erhalten. Wenn ich jedoch die Positionen der Kugeln als separate Einheiten bearbeiten kann, dauert dies nur 4 * 10 = 40 Bytes. Das passt in einen Cache-Abruf. Somit erhalten wir nur 1 Cache-Fehler, um alle 10 Bälle zu aktualisieren. Diese Zahlen sind willkürlich - ich gehe davon aus, dass ein Cache-Block größer ist.
Es zeigt jedoch, wie sich das Speicherlayout stark auf die Cache-Treffer und damit auf die Leistung auswirken kann. Dies wird nur an Bedeutung gewinnen, wenn sich der Unterschied zwischen CPU- und RAM-Geschwindigkeit vergrößert.
So gestalten Sie den Speicher
In meinem Ball-Beispiel habe ich das Problem stark vereinfacht, da Sie normalerweise für jede normale App wahrscheinlich gleichzeitig auf mehrere Variablen zugreifen. ZB werden Position und Radius wahrscheinlich häufig zusammen verwendet. Dann sollte Ihre Struktur sein:
Der Grund, warum Sie dies tun sollten, ist, dass, wenn Daten zusammen in separaten Arrays abgelegt werden, das Risiko besteht, dass sie um dieselben Slots im Cache konkurrieren. Wenn Sie also einen laden, wird der andere weggeworfen.
Im Vergleich zur objektorientierten Programmierung beziehen sich die Klassen, die Sie am Ende erstellen, nicht auf die Entitäten in Ihrem mentalen Modell des Problems. Da Daten basierend auf der Datennutzung zusammengefasst werden, haben Sie nicht immer sinnvolle Namen, um Ihren Klassen in datenorientiertem Design zu geben.
Beziehung zu relationalen Datenbanken
Das Denken hinter Data Oriented Design ist sehr ähnlich zu dem, was Sie über relationale Datenbanken denken. Das Optimieren einer relationalen Datenbank kann auch eine effizientere Verwendung des Caches beinhalten, obwohl in diesem Fall der Cache kein CPU-Cache, sondern Seiten im Speicher ist. Ein guter Datenbankdesigner wird wahrscheinlich auch Daten, auf die selten zugegriffen wird, in eine separate Tabelle aufteilen, anstatt eine Tabelle mit einer großen Anzahl von Spalten zu erstellen, wenn nur einige der Spalten jemals verwendet werden. Er kann sich auch dafür entscheiden, einige der Tabellen zu denormalisieren, damit nicht von mehreren Stellen auf der Festplatte auf Daten zugegriffen werden muss. Genau wie bei Data Oriented Design werden diese Entscheidungen getroffen, indem untersucht wird, wie die Datenzugriffsmuster aussehen und wo der Leistungsengpass liegt.
quelle
struct balls {vector<vec3> pos; vector<vec3> velocity;}
, die nicht aktualisiert, dass die Position jedes Balls den Cache tatsächlich zerstört, da Sie sich zwischen dem Geschwindigkeitsvektor und dem Positionsvektor hin und her bewegen würden (ja, moderne Maschinen und Cache-Zeilen und all das, das ist auch nur eine Illustration)?struct balls { vector<color> colors; vector<body> bodies; /* contains position and velocity */ }
.Mike Acton hielt kürzlich einen öffentlichen Vortrag über datenorientiertes Design :
Meine grundlegende Zusammenfassung wäre: Wenn Sie Leistung wünschen, dann denken Sie über den Datenfluss nach, finden Sie die Speicherschicht, die am wahrscheinlichsten mit Ihnen zusammenpasst, und optimieren Sie sie hart. Mike konzentriert sich auf L2-Cache-Fehler, weil er in Echtzeit arbeitet, aber ich stelle mir vor, dass dies auch für Datenbanken (Festplattenlesevorgänge) und sogar für das Web (HTTP-Anforderungen) gilt. Ich denke, es ist eine nützliche Methode zur Systemprogrammierung.
Beachten Sie, dass Sie nicht über Algorithmen und Zeitkomplexität nachdenken müssen, sondern sich nur darauf konzentrieren, den teuersten Operationstyp herauszufinden, auf den Sie dann mit Ihren verrückten CS-Fähigkeiten abzielen müssen.
quelle
Ich möchte nur darauf hinweisen, dass Noel speziell über einige der spezifischen Bedürfnisse spricht, denen wir bei der Spieleentwicklung gegenüberstehen. Ich nehme an, andere Sektoren, die eine weiche Echtzeitsimulation durchführen, würden davon profitieren, aber es ist unwahrscheinlich, dass es sich um eine Technik handelt, die eine spürbare Verbesserung der allgemeinen Geschäftsanwendungen zeigt. Diese Einrichtung soll sicherstellen, dass die zugrunde liegende Hardware bis zum letzten Stück Leistung herausgefordert wird.
quelle
Ein datenorientiertes Design ist ein Design, bei dem die Logik der Anwendung aus Datensätzen anstelle von prozeduralen Algorithmen aufgebaut ist. Beispielsweise
prozeduraler Ansatz.
Datenentwurfsansatz
Datenentwürfe wie dieser fördern die Verwendung von Daten, um die Logik der Anwendung zu erstellen. Es ist einfacher zu verwalten, insbesondere in Videospielen, die möglicherweise Tausende von Logikpfaden haben, die auf Animationen oder einem anderen Faktor basieren.
quelle