Es war einmal, als > schneller war als < ... Warte, was?

Lesezeit: 6 Minuten

Benutzeravatar von Armen Tsirunyan
Armen Tsirunjan

ich lese ein tolles OpenGL-Tutorial. Es ist wirklich toll, vertrau mir. Das Thema, bei dem ich mich gerade befinde, ist Z-Puffer. Abgesehen von der Erklärung, worum es geht, erwähnt der Autor, dass wir benutzerdefinierte Tiefentests wie GL_LESS, GL_ALWAYS usw. durchführen können. Er erklärt auch, dass die tatsächliche Bedeutung von Tiefenwerten (was oben ist und was nicht) auch sein kann angepasst. Ich verstehe soweit. Und dann sagt der Autor etwas Unglaubliches:

Die Reichweite zNah kann größer sein als die Reichweite zFar; wenn dies der Fall ist, werden die Fensterabstandswerte umgekehrt, in Bezug darauf, was am nächsten oder am weitesten vom Betrachter entfernt ist.

Früher wurde gesagt, dass der Fensterraum-Z-Wert von 0 am nächsten und 1 am weitesten ist. Wenn jedoch unsere Clipspace-Z-Werte negiert würden, wäre die Tiefe von 1 der Ansicht am nächsten und die Tiefe von 0 am weitesten entfernt. Wenn wir jedoch die Richtung des Tiefentests umkehren (GL_LESS zu GL_GREATER usw.), erhalten wir genau das gleiche Ergebnis. Es ist also wirklich nur eine Konvention. In der Tat war das Umdrehen des Zeichens von Z und der Tiefentest einst eine wichtige Leistungsoptimierung für viele Spiele.

Wenn ich das richtig verstehe, ist das Umdrehen des Z-Zeichens und der Tiefentest leistungsmäßig nichts anderes als das Ändern von a < Vergleich zu a > Vergleich. Also, wenn ich das richtig verstehe und der Autor nicht lügt oder Dinge erfindet, dann ändert er sich < zu > früher war eine wichtige Optimierung für viele Spiele.

Hat sich der Autor etwas ausgedacht, habe ich etwas falsch verstanden, oder ist das tatsächlich einmal so < war langsamer (lebenswichtigwie der Autor sagt) als >?

Vielen Dank für die Klärung dieser ziemlich merkwürdigen Angelegenheit!

Haftungsausschluss: Mir ist vollkommen bewusst, dass die Komplexität von Algorithmen die Hauptquelle für Optimierungen ist. Außerdem vermute ich, dass es heutzutage definitiv keinen Unterschied machen würde, und ich frage dies nicht, um irgendetwas zu optimieren. Ich bin nur extrem, schmerzhaft, vielleicht unerschwinglich neugierig.

  • (a < b) ist identisch mit (b > a), sodass es absolut nicht erforderlich ist, beide Vergleichsoperationen in Hardware zu implementieren. Der Leistungsunterschied ist das Ergebnis dessen, was als Ergebnis der Vergleichsoperation passiert. Dies ist ein langer und kurvenreicher Weg, um alle Nebenwirkungen zu erklären, aber hier sind ein paar Hinweise. Spiele zum Füllen des Tiefenpuffers, um eine teurere Fragmentverarbeitung für Fragmente zu vermeiden, die den Tiefentest nicht bestanden haben. Quake hat früher den Tiefenbereich in zwei Hälften geteilt, um zu vermeiden, dass der Framebuffer gelöscht wird, da das Spiel immer jedes Pixel auf dem Bildschirm füllte und so weiter.

    – t0rakka

    27. Dezember 2017 um 14:24 Uhr


  • Hier ist der archivierte Version des referenzierten OpenGL-Tutorials. Ich kann das zitierte Snippet jedoch nicht finden, vielleicht wurde es herausgenommen.

    – Telefon

    8. Juli 2018 um 13:03 Uhr


Wenn ich das richtig verstehe, ist das Umdrehen des Z-Zeichens und des Tiefentests nichts anderes als das Ändern eines <-Vergleichs in einen >-Vergleich. Also, wenn ich das richtig verstehe und der Autor nicht lügt oder etwas erfindet, dann war das Ändern von < zu > früher eine wichtige Optimierung für viele Spiele.

Ich habe das nicht besonders gut erklärt, weil es nicht wichtig war. Ich hatte nur das Gefühl, dass es eine interessante Trivia war, die ich hinzufügen konnte. Ich wollte nicht speziell auf den Algorithmus eingehen.

Der Kontext ist jedoch entscheidend. Ich habe nie gesagt, dass ein <-Vergleich schneller ist als ein >-Vergleich. Denken Sie daran: Wir sprechen von Tiefentests der Grafikhardware, nicht von Ihrer CPU. Nicht operator<.

Worauf ich mich bezog, war eine bestimmte alte Optimierung, bei der Sie einen Frame verwenden würden GL_LESS mit einer Reihe von [0, 0.5]. Nächstes Bild, mit dem Sie rendern GL_GREATER mit einer Reihe von [1.0, 0.5]. Sie gehen hin und her und “drehen buchstäblich das Zeichen von Z und den Tiefentest um” bei jedem Frame.

Dadurch geht ein bisschen Tiefenpräzision verloren, aber Sie mussten den Tiefenpuffer nicht löschen, was früher eine ziemlich langsame Operation war. Da die Tiefenreinigung heutzutage nicht nur kostenlos, sondern sogar schneller als diese Technik ist, wird sie nicht mehr angewendet.

  • Der Grund, warum das Löschen des Tiefenpuffers heutzutage schneller ist, hat zwei Gründe, die beide auf der Tatsache beruhen, dass die GPU einen hierarchischen Tiefenpuffer verwendet. Dazu muss nur der Kachelstatus gelöscht werden (was schnell geht), das Ändern des Tiefenvergleichszeichens bedeutet jedoch, dass der gesamte HiZ-Puffer geleert werden muss, da er je nach Vergleichszeichen nur einen Mindest- oder Höchstwert speichert.

    – Jaspis Bekkers

    29. Juni 2012 um 19:41 Uhr

  • @NicolBolas: PerTZHXs Kommentar, der Link zu Ihrem Tutorial in meiner Frage ist tot. Könnten Sie uns bitte alle mitteilen, wohin die Tutorials verschoben wurden, und gegebenenfalls die Frage bearbeiten, bitte?

    – Armen Tsirunyan

    24. März 2015 um 12:57 Uhr

  • Die Tutorials sind im Webarchiv verfügbar. Wenn @NicolBolas dies zulässt, wäre es für die Community hilfreich, wenn wir sie an einen besser zugänglichen Ort verlegen könnten. Vielleicht GitHub oder so. web.archive.org/web/20150215073105/http://arcsynthesis.org/…

    – ApoorvaJ

    27. Juni 2015 um 13:21 Uhr

Die Antwort ist mit ziemlicher Sicherheit, dass für welche Inkarnation von Chip + Treiber auch immer das hierarchische Z nur in eine Richtung funktionierte – dies war damals ein ziemlich häufiges Problem. Low-Level-Assemblierung/Verzweigung hat damit nichts zu tun – Z-Pufferung erfolgt in Hardware mit fester Funktion und wird in Pipelines geleitet – es gibt keine Spekulation und daher keine Verzweigungsvorhersage.

Joshuas Benutzeravatar
Josua

Es hat mit Flag-Bits in hoch abgestimmter Anordnung zu tun.

x86 hat sowohl jl- als auch jg-Anweisungen, aber die meisten RISC-Prozessoren haben nur jl und jz (kein jg).

  • Wenn das die Antwort ist, wirft sie neue Fragen auf. War “Verzweigung genommen” bei frühen RISC-Prozessoren langsamer als “Verzweigung ignoriert”? Soweit ich weiß, ist das jetzt sicherlich nicht messbar so. Hättest du schreiben sollen for Schleifen mit einem unbedingten Sprung rückwärts und einem bedingten, selten genommenen Sprung vorwärts, um die Schleife dann zu verlassen? Klingt umständlich.

    – Pascal Cuoq

    7. September 2011 um 19:43 Uhr


  • -1: Diese Frage hat nichts mit CPUs zu tun. GL_LESS und GL_GREATER sind Tiefenvergleichsoperationen, die auf GPUs ausgeführt werden.

    – Nicol Bolas

    7. September 2011 um 20:29 Uhr

  • Komisch, wie viel Wiederholung man für eine Antwort bekommen kann, die zum Titel passt, aber sehr wenig mit der eigentlichen Frage zu tun hat.

    – Josua

    8. September 2011 um 1:12 Uhr

  • +1 Nein, diese Antwort ist zumindest teilweise richtig. Die Frage ist: “Erfindet sich der Autor etwas, verstehe ich etwas falsch, oder war es tatsächlich so, dass < einmal langsamer war (lebenswichtig, wie der Autor sagt) als >?”. Es werden drei Optionen angeboten. Diese Antwort reagiert auf die Möglichkeit von Option 3. Nirgendwo in dem Artikel wird die Technologie der CPU / GPU angegeben, noch dass es sich um eine GPU handeln muss (erste 3D-Spiele, bei denen eine CPU verwendet wird). Ok … Ich glaube nicht, dass es viele 3D-Spiele auf RISC gab 🙂

    – xanatos

    14. September 2011 um 9:57 Uhr

  • (und das GPU-Tag wurde um 20:34 hinzugefügt. Die erste Revision hatte nur das CPU-Tag. Diese Antwort wurde um 18:44 geschrieben.)

    – xanatos

    14. September 2011 um 10:12 Uhr

1426700cookie-checkEs war einmal, als > schneller war als < ... Warte, was?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy