Frage

Es hat eine weitere Frage auf welche Daten orientiertes Design ist, und es gibt einen Artikel , die oft bezeichnet wird (und ich habe es wie 5 oder 6 mal gelesen bereits). Ich verstehe das allgemeine Konzept dieser, vor allem, wenn sie mit zu tun, beispielsweise 3D-Modelle, in dem Sie alle Scheiteln zusammenhalten möchte, und nicht verschmutzen Ihre Gesichter mit Normalen, etc.

Aber ich habe eine harte Zeit zu visualisieren, wie datenorientierte Design funktionieren könnte für alles andere als die banalsten Fällen (3D-Modelle, Partikel, BSP-Bäume, und so weiter). Gibt es gute Beispiele gibt, die wirklich datenorientierte Design und zeigt, wie diese Macht in der Praxis umfasst? Ich kann große Code-Basen durchpflügen, wenn nötig.

Was mich interessiert vor allem in ist das Mantra „wo es eine gibt es viele“, die ich mit dem Rest nicht wirklich scheinen hier zu verbinden. Ja, es gibt immer mehr als einen Feind, noch müssen Sie noch jeden Gegner einzeln aktualisieren, weil sie nicht die gleiche Art und Weise jetzt bewegen sind sie? Das Gleiche gilt für das ‚balls'-Beispiel in der akzeptierten Antwort auf die Frage oben (ich tatsächlich gefragt, dies in einem Kommentar zu dieser Antwort, aber noch keine Antwort bekommen noch). Ist es einfach, dass die Wiedergabe nur die Positionen benötigt, und nicht die Geschwindigkeiten, während die Spielsimulation beide braucht, aber nicht das Material? Oder bin ich etwas fehlt? Vielleicht habe ich verstehe es schon und es ist ein weit einfacheres Konzept als ich dachte.

Alle Hinweise wäre sehr willkommen!

War es hilfreich?

Lösung

Also, was ist DOD alles? Offensichtlich geht es um Leistung, aber es ist nicht nur das. Es geht auch um gut gestalteten Code, lesbar, leicht zu verstehen und auch wiederverwendbar. Jetzt die objektorientierte Design ist über die Code- und Daten Gestaltung in gekapselte virtuelle „Objekte“ passen. Jedes Objekt ist eine separate Einheit mit Variablen für Eigenschaften dieses Objekt könnte und Methoden müssen Maßnahmen zu ergreifen, um sich selbst oder andere Gegenstände in der Welt. Der Vorteil des OO-Designs ist, dass es einfach den Code in Objekte zu geistig modelliert, weil die ganze (real) Welt um uns herum zu arbeiten in der gleichen Art und Weise scheint. Objekte mit Eigenschaften, die miteinander in Wechselwirkung treten können.

Jetzt ist das Problem, dass die CPU in Ihrem Computer in eine völlig andere Art und Weise funktioniert. Es funktioniert am besten, wenn Sie lassen es die gleichen Dinge tun immer wieder. Warum das? Wegen ein kleines Ding Cache genannt. Zugriff RAM auf einem modernen Computer kann 100 oder 200 CPU-Zyklen dauern (und die CPU muss die ganze Zeit warten!), Was viel zu lang ist. So gibt es diesen kleinen Teil des Speichers auf der CPU, die wirklich schnell zugegriffen werden können, Cache-Speicher. Das Problem ist, es ist nur ein paar MB Tops. Also jedes Mal, wenn Sie Daten benötigen, die nicht im Cache war, müssen Sie noch den langen Weg in den RAM gehen. Das ist nicht nur auf diese Weise für Daten, die gleichen für Code geht. Der Versuch, eine Funktion auszuführen, die nicht im Befehlscache ist ein Stall führen, während der Code aus dem RAM geladen wird.

Zurück zur OO-Programmierung. Objekte sind groß, aber die meisten Funktionen benötigen nur einen kleinen Teil der Daten, so dass wir verschwenden Cache durch unnötigen Daten geladen werden. Methoden aufrufen, andere Methoden, die andere Methoden aufrufen, Ihre Befehlscache Dreschen. Trotzdem tun wir oft eine Menge von den gleichen Sachen immer und immer wieder. Lassen Sie sich von einem Spiel zum Beispiel eine Kugel nehmen. In einer naiven Implementierung könnte jede Kugel ein separates Objekt sein. Es könnte eine Kugel Managerklasse sein. Es ruft die Update-Funktion der ersten Kugel. Es aktualisiert die 3D-Position mit der Richtung / Geschwindigkeit. Dies bewirkt, dass eine Menge anderer Daten aus dem Objekt in den Cache geladen werden. Als nächstes rufen wir den Weltmanager-Klasse für eine Kollision mit anderen Objekten zu überprüfen. Dies lädt viele andere Sachen in den Cache, vielleicht sogar bewirkt, dass es Code aus dem ursprünglichen Klasse Kugel-Manager aus dem Befehlscache fallen gelassen werden. Nun kehren wir zur Kugel zu aktualisieren, es gab keine Kollision, so dass wir zu Kugel-Manager zurückzukehren. Es muss möglicherweise wieder einige Code laden. Weiter oben, Kugel # 2 Update. Dies lädt eine Menge Daten in den Cache, Anrufe Welt ... etc. Also in diesem hypthetical Situation haben wir zwei Stände für das Laden Code bekommen und sagen wir mal 2 Ständen zum Laden von Daten. Das ist, mindestens 400 Zyklen verschwendet, für 1 Kugel, und wir haben nicht getroffen Kugeln, die etwas anderes in Betracht getroffen. Nun wird ein CPU läuft mit 3 + GHz, so werden wir nicht zu bemerken, eine Kugel, aber was, wenn wir 100 Kugeln haben? Oder noch mehr?

Das ist also die, wo gibt es eine gibt viel Geschichte. Ja, es gibt einige Fälle, in denen Sie nur auf das Objekt haben, Ihre Manager-Klassen, Dateizugriff, etc. Aber öfter gibt es viele ähnliche Fälle. Naive oder gar nicht-naives objektorientiertes Design wird viele Probleme führen. So geben Sie die Daten orientiertes Design. Der Schlüssel des DOD ist Ihren Code um Ihre Daten zu modellieren, nicht umgekehrt wie bei OO-Design. Dies beginnt bei den ersten Stufen des Designs. Sie entwerfen nicht zuerst Ihren OO-Code und dann optimieren. Sie beginnen mit der Auflistung und Ihre Daten zu prüfen und zu denken, wie Sie es ändern wollen (ich auf ein praktisches Beispiel in einem Moment zu bekommen). Sobald Sie wissen, wie Sie Ihren Code, um die Daten zu ändern, wird können Sie es lag in einer Art und Weise, dass es so effizient wie möglich macht, sie zu verarbeiten. Nun können Sie denken, dies nur für eine schreckliche Suppe von Code und Daten überall führen kann, aber das ist nur der Fall, wenn Sie es entwerfen schlecht (schlechtes Design ist genauso einfach mit OO-Programmierung). Wenn Sie es gut Design, Code und Daten können ordentlich um spezifische functio gestaltet werden,nalität, was zu einer sehr gut lesbar und sogar sehr wieder verwendbaren Code.

Also zurück zu unseren Kugeln. Statt eine Klasse für jede Kugel zu schaffen, halten wir nur die Kugel-Manager. Jede Kugel hat eine Position und eine Geschwindigkeit. Jede Kugel Bedürfnisse Position aktualisiert werden. Jede Kugel hat eine Kollisionsprüfung und alle Kugeln haben, die Hit etwas Notwendigkeit haben, eine Aktion entsprechend zu nehmen. Also einfach durch einen Blick auf diese Beschreibung nehmen kann ich Design dieses ganze System in einem viel besseren Weg. Sagen wir die Positionen aller Kugeln in einem Array / Vektor. Sagen wir, die Geschwindigkeit aller Kugeln in einem Array / Vektor. Nun lasst uns beginnen, indem allong diese beiden Arrays iteriert und jeder Positionswert zu aktualisieren damit Geschwindigkeit ist entsprechend. Nun werden alle in die Datencache geladen Daten Daten, die wir verwenden werden. Wir können sogar einen Smart Vorbelastung Befehl setzen bereits einige Array-Daten im Voraus Vorbelastung, so dass die Daten der im Cache, wenn wir es bekommen. Als nächste Kollisionsprüfung. Ich werde nicht ins Detail hier, aber man kann sich vorstellen, wie alle Kugeln hintereinander kann helfen, zu aktualisieren. Beachten Sie auch, dass, wenn es eine Kollision ist, wir nicht eine neue Funktion oder alles tun, nennen würde. Wir halten nur einen Vektor mit allen Kugeln, die Kollision hatte und bei Kollisionsprüfung durchgeführt wird, können wir alle diejenigen, die nach einander aktualisieren. Sehen Sie, wie wir gingen gerade von vielen Speicherzugriff auf fast keiner von unseren Daten zur Festlegung anders aus? Haben Sie auch feststellen, wie unser Code und Daten, auch wenn entworfen nicht in einem OO-Weg mehr, sind immer noch leicht zu verstehen und leicht zu Wiederverwendung?

So zum zu kommen „wo gibt es eine gibt viele ist“. Wenn OO-Code entwerfen denken Sie über ein Objekt, den Prototyp / Klasse. Eine Kugel hat eine Geschwindigkeit, eine Kugel, eine Position hat, wird eine Kugel jeden Frame Geschwindigkeit des durch sie bewegt, kann eine Kugel etwas getroffen, etc. Wenn Sie darüber nachdenken, werden Sie über eine Klasse denken, mit der Geschwindigkeit, Position und einem Update-Funktion, die die Kugel und prüft, ob Kollision bewegt. Wenn Sie jedoch mehrere Objekte haben müssen Sie über alle von ihnen denken. Kugeln haben Positionen, Geschwindigkeit. Einige Kugeln können Kollision haben. Sehen Sie, wie wir nicht über ein einzelnes Objekt nicht mehr zu denken? Wir denken über alle von ihnen und entwerfen Code viel anders jetzt.

Ich hoffe, das hilft der Antwort auf Ihren zweiten Teil der Frage. Es geht nicht darum, ob Sie jeden Feind aktualisieren müssen oder nicht, es geht um die effizienteste Weg, um sie zu aktualisieren. Und während der Gestaltung nur Ihre Gegner mit DOD kann keine Hilfe gewinnen viel Leistung, das gesamte Spiel entwerfen, um diese Prinzipien (nur falls anwendbar!) Kann auf eine Menge von Leistungssteigerungen führen!

So auf den ersten Teil der Frage ist, dass andere Beispiele für DOD. Es tut mir leid, aber ich habe nicht so viel da. Es ist ein wirklich gutes Beispiel wenn ich über diese vor einiger Zeit kam eine Reihe von Daten orientierte Gestaltung eines Verhaltens Baum von Bjoern Knafla:

Andere Tipps

las ich die Frage, die Sie verknüpfen und den Artikel.

Ich habe ein Buch über das Thema Datenlese Driven Design.

Ich bin so ziemlich im gleichen Boot wie Sie.

So wie ich Noels Artikel verstehen ist, dass Sie entwerfen Ihr Spiel im typischen objektorientierten Art und Weise. Sie haben Klassen und Methoden, die Arbeit an den Klassen.

Nachdem Sie Ihr Design gemacht haben, fragen Sie sich die folgenden Fragen:

Wie kann ich alle Daten anordnen ich in einem großen Klecks entworfen haben?

Denken Sie daran, in Bezug auf das gesamte Design als eine funktionale Methode, mit vielen untergeordneten Methoden zu schreiben. Es erinnert mich an den massiven 500.000 Linie Cobol Programme meiner Jugend.

Nun, werden Sie wahrscheinlich nicht das gesamte Spiel als eine große funktionale Methode schreiben. Wirklich, in dem Artikel, Noel spricht über den Rendering Teil eines Spiels. Betrachten Sie es als einen Spiel-Engine (die große funktionale Methode) und der Code den Game-Engine (der OOP-Code) zu fahren.

  

Was mich interessiert vor allem in ist das Mantra „wo es eine gibt es viele“, die ich mit dem Rest nicht wirklich scheinen hier zu verbinden. Ja, es gibt immer mehr als einen Feind, noch müssen Sie noch jeden Gegner einzeln aktualisieren, weil sie nicht die gleiche Art und Weise jetzt sind sie zu verschieben?

Sie sind in Bezug auf die Objekte zu denken. Versuchen Sie, in Bezug auf Funktionalität zu denken.

Jeder Feind Update ist eine Iteration einer Schleife.

Wichtig ist, dass der Feind Daten strukturiert in einem Speicherplatz zu sein, anstatt die sie über feindliches Objekt Instanziierungen.

scroll top