Beim Lesen von Artikeln finde ich häufig Oct-Tree-Implementierungen von Geometriedarstellungen, um die Daten zu sortieren. Wenn ich jedoch über das Problem nachdenke, scheinen Hash-Tabellen insgesamt besser zu sein.
Hash-Tabellen bieten für die meisten Anwendungen bessere Durchschnitts- und schlechtere Szenarien:
Wenn Sie beispielsweise einen Okt-Baum durch Raytracing verfolgen, werden Sie durch Beinaheunfälle durch eine binäre Baumsubstruktur iteriert, die O (nlogn) ist, während die Hash-Tabelle O (n) ist.
Hash-Tabellen sind in der GPU einfacher zu generieren, da sie keine andere logische Position im Speicher als ihre Hash-Position benötigen.
Die meisten Vorteile, die Baumstrukturen gegenüber Hash-Tabellen haben, scheinen auch auf der GPU nicht zu gelten.
In Grafiken mögen wir es nicht, Speicher neu zuzuweisen, daher weisen wir normalerweise zu viel Speicher im VRAM zu, um eine Datenstruktur wiederverwenden zu können. Daher scheinen die Eigenschaften von Binärbäumen (speichereffizient) für GPU-Anwendungen nicht sehr relevant zu sein.
Die Datenkohärenz für das Caching scheint ebenfalls nicht zu gelten. Bei einem GPU-generierten Baum ist es aufgrund der Asynchronität sehr schwierig zu gewährleisten, dass logisch geschlossene Werte auch im zugrunde liegenden Speicher nahe beieinander gespeichert werden. Sie werden also sowieso um Zeiger herumspringen.
Es ist auch viel einfacher, bestimmte GPU-freundliche Heuristiken in einer Hash-Tabelle zu erzwingen als in einem Baum. Begrenzen Sie beispielsweise die Anzahl der Hash-Lookups auf eine feste Anzahl, z. B. 20, und verwenden Sie dieselbe Logik, um zu verhindern, dass Warps unterschiedliche Verzweigungscodes ausführen. Im Wesentlichen können Sie immer die 20 möglichen Kollisionen überprüfen und das Ergebnis einfach mit der Zelle interpolieren, die den Schlüssel enthält. In einem Baum hängt das Durchlaufen der Datenstruktur viel mehr von den Daten selbst und weniger von der Datenstruktur ab.
Warum werden Okt-Bäume so viel häufiger verwendet als Hash-Tabellen?
Antworten:
Meine 2 Cent beim Schreiben der Chipmunk2D-Physik-Engine sind, dass räumliches Hashing großartig ist, wenn Sie viele Objekte haben, die alle gleich groß sind. Ich hatte vor 10 Jahren eine Demo, die mit 20.000 interagierenden Partikeln auf einem Core 2 Duo in Echtzeit lief. Der räumliche Hash hat dafür hervorragend funktioniert, wenn Sie ihn optimiert haben .
Ich habe seitdem den räumlichen Hash durch einen binären AABB-Baum als Standardstruktur ersetzt. Es ist alles andere als perfekt, aber es war im Durchschnitt schneller als der räumliche Hash ohne Abstimmung . Es war auch einfacher, eine zeitliche Komponente hinzuzufügen, damit ich eine Reihe potenzieller Kollisionen schrittweise aktualisieren konnte. Mit all dem war der einzige Test, den ich hatte, der mit dem räumlichen Hash schneller lief, der mit Tausenden von Partikeln und ohne statische Geometrie.
Was Octrees betrifft ... Meh, ich benutze sie nie. Grundlegende Quad / Octrees passen nicht wirklich zu realen Daten sowie zu der Fülle anderer BVHs, die Sie verwenden können. Grund AABB Bäume sind fast so einfach und Weise effektiver.
quelle
Viele Dinge hier.
"Beim Lesen von Zeitungen". Welche Papiere? Wenn es bei dem Thema des Papiers um etwas anderes als die räumliche Aufteilungsstruktur geht, kann es fair sein, alles zu verwenden, wenn man weiß, dass die Grundideen auf andere Strukturen übertragen werden. Oder nicht, schwer zu sagen.
"Zum Beispiel für die Raytracing-Funktion eines Okt-Baums führen Beinahe-Fehler dazu, dass Sie eine binäre Baum-Substruktur durchlaufen, die O (nlogn) ist, während die Hash-Tabelle O (n) ist." Big O-Notation bedeutet in diesem Zusammenhang überhaupt nichts. Sie haben es mit einer bestimmten Technologie in einem bestimmten Maßstab zu tun, wenn Sie über Dinge sprechen, die von Implementierungsdetails abhängen. Ein O (nlogn) -Algorithmus ist möglicherweise viel langsamer als ein O (n) -Algorithmus für das "n", was heute realistisch ist. Es kommt immer wieder vor. Und während Sie vielleicht sagen, dass sich dies in 10 Jahren ändern könnte, könnte dies der Fall sein, aber in denselben 10 Jahren könnte Ihre GPU völlig anders aussehen und daher müssen sich die Algorithmen auf dem neuesten Stand der Technik unabhängig davon ändern. Dies ist häufig der Fall, wenn Sie sich GPU-Algorithmen ansehen (und GPUs entwickeln sich noch ziemlich weit).
Welcher Octree? Welche Hash-Tabelle? Dort gibt es viele Möglichkeiten. Zum Beispiel "... da sie keine andere logische Position im Speicher als ihre Hash-Position benötigen". Das stimmt nur, wenn Sie keine Hash-Kollisionen haben, ja? Wenn Sie Kollisionen haben, müssen Sie unabhängig von der von Ihnen verwendeten Strategie (Prüfung oder verknüpfte Listen) zwischen Threads synchronisieren, damit der Build auf einer GPU nicht so einfach implementiert werden kann. Umgekehrt könnten Sie für Oktrees, wenn Sie wie von Ihnen vorgeschlagen "insgesamt zuordnen" möchten, einen vollständigen Baum zuweisen, und die Indizierung wäre dann ebenfalls nur von der Position abhängig. In der Tat, wenn Sie etwas rechnen, können Sie sehen, dass in solchen Fällen Oktrees nur eine Möglichkeit sind, ein Raster zu verwirren (z. B. vergleichen Sie das Van-Ende-Boas-Layout mit einem Raster in Morton-Reihenfolge ... schöne Übung).
Es gibt viele andere Dinge, die ich sagen könnte, aber lassen Sie mich hier zur Sache kommen.
Für das Raytracing sind weder Octrees noch Hash-Tabellen so beliebt. BVHs von AABBs sind der richtige Weg.
Der Hauptvorteil von Octrees gegenüber dem Hash-Raster besteht darin, dass sich Ihre Zellenauflösung an die Geometrie anpasst. Raster werden nicht, Sie müssen eine Zellengröße auswählen, die in bestimmten Teilen der Szene zu klein und in bestimmten anderen zu groß sein kann.
Es gibt eine Vielzahl von Varianten und eine Vielzahl von Implementierungsdetails. Naive Octrees sollten in der Praxis wahrscheinlich nie verwendet werden, da sie zu tief / nicht breit genug sind. Wenn Sie ein Octree "größer" machen, indem Sie beispielsweise ein 4x4x4-Gitter mit 4x4x4-Gittern in jeder nicht leeren Zelle verschachteln, erstellen Sie ein sogenanntes hierarchisches Gitter. Gitter und Oktrees existieren also in einem Spektrum, in dem Oktrees am "tiefsten" sind, Gitter am "flachsten" sind (nur eine Ebene, ein einzelnes Gitter global in der Szene) und hierarchische Gitter zwischen den beiden handeln können
Das könnte helfen! http://www.realtimerendering.com/Real-Time_Rendering_4th-Real-Time_Ray_Tracing.pdf ;)
quelle