Implementierung von Algorithmen über Compute-Shader im Vergleich zu Pipeline-Shadern

10

Mit der Verfügbarkeit von Compute-Shadern für DirectX und OpenGL ist es jetzt möglich, viele Algorithmen zu implementieren, ohne die Rasterisierungs-Pipeline zu durchlaufen, und stattdessen Allzweck-Computing auf der GPU zu verwenden, um das Problem zu lösen.

Für einige Algorithmen scheint dies die intuitive kanonische Lösung zu sein, da sie von Natur aus nicht auf Rasterung basieren und Shaster auf Rasterisierung eine Problemumgehung darstellen, um die GPU-Leistung zu nutzen (einfaches Beispiel: Erstellen einer Rauschtextur. Hier muss kein Quad gerastert werden ).

Gibt es bei einem Algorithmus, der in beide Richtungen implementiert werden kann, allgemeine (potenzielle) Leistungsvorteile gegenüber der Verwendung von Compute-Shadern im Vergleich zum normalen Weg? Gibt es Nachteile, auf die wir achten sollten (gibt es zum Beispiel einen ungewöhnlichen Overhead beim Umschalten von / auf das Berechnen von Shadern zur Laufzeit)?

Gibt es vielleicht andere Vor- oder Nachteile, die bei der Wahl zwischen beiden zu berücksichtigen sind?

TravisG
quelle
Wenn das Performance-Tag tatsächlich relevant ist, sollten Sie dieses Video aus dem Artikel "Cloth Simulation" von Game Engine Gems von Marco Fratarcangeli ansehen: youtube.com/watch?v=anNClcux4JQ . Sie konnten die Kommentare lesen und etwas Unangenehmes herausfinden: Die GLSL / Shader-basierte Implementierung war schneller als die Verwendung von CUDA oder OpenCL (letztere aufgrund der schlechten Treiberunterstützung zu diesem Zeitpunkt im Jahr 2010). Es gibt bestimmte Unterschiede auf niedriger Ebene, die einen Unterschied machen.
Teodron
@teodron Ich habe keine GPU Gems zur Verfügung und kann den Quellcode nicht finden. Hat der Autor tatsächlich GLSL-Vertex + Pixel-Shader verwendet oder hat er GLSL-Compute-Shader verwendet?
TravisG
Ja! Vor CUDA implementierte die Community auf diese Weise GPGPU-Funktionen. Hier ist ein Link zu OpenCloth, um zu sehen, wie man genau das mit reinem GLSL ODER Cuda erreichen kann: code.google.com/p/opencloth/source/browse/trunk/…
teodron

Antworten:

7

Es gibt keine richtige Antwort, wenn Sie direkt von der Berechnung von Compute Shadrs / GPGPU profitieren möchten. Dies hängt stark von der Art des von Ihnen implementierten Algorithmus ab. Compute Shader und CUDA / OpenCL sind ein allgemeinerer Ansatz, um einige der Einschränkungen zu überwinden von diesen alten Shading-Sprachen hacken. Die wichtigsten Vorteile, die Sie erhalten:

  • Zugriff auf räumliche Informationen. im alten GLSL-Hack (nun, es war ein Hack!) gibt es nur wenige Informationen über Nachbarfragmente, da Texturkoordinaten verwendet werden. In Compute Shadern / CUDA / OpenCL ist der Zugriff auf räumliche Informationen viel flexibler. Sie können jetzt Algorithmen wie den Histogrammausgleich auf der GPU mit ungeordnetem Textur- / Pufferzugriff implementieren .
  • Gibt Ihnen Thread- Synchronisation und Atomics .
  • Rechenraum: Der alte GLSL-Hack verdrahtet den Vertex / Fragment-Rechenraum fest mit Ihrem Shader. Der Fragment-Shader wird mit der Anzahl der Fragmente ausgeführt, der Vertex-Shader mit der Anzahl der Scheitelpunkte. Im Compute Shader definieren Sie Ihren eigenen Raum.
  • Skalierbarkeit : Ihr Compute Shader / CUDA / OpenCL kann im Gegensatz zu Ihrem alten GLSL-Shader, der auf demselben SM ausgeführt werden soll, auf die Anzahl der verfügbaren GPU-SMs (Streaming Multiprocessor) skaliert werden. (Basierend auf den Kommentaren von Nathan Reed sagt er, dass dies nicht der Fall ist und dass Shader so gut skaliert werden sollten wie Compute-Shader. Ich bin mir immer noch nicht sicher, ob ich die Dokumentation überprüfen muss.)
  • Kontextwechsel : Es sollte einige Kontextwechsel geben, aber ich würde sagen, dass dies von der Anwendung abhängt. Daher ist es am besten, Ihre Anwendung zu profilieren.

Nun , in meiner Meinung nach , wenn Sie die Compute Shaders Weg gehen wollen, auch wenn bestimmte Algorithmen sein können besser geeignet, gibt es bestimmte Überlegungen , die Sie brauchen , zu berücksichtigen:

  1. Hardware- und Abwärtskompatibilität . Compute-Shader sind nur in neuerer Hardware verfügbar. Wenn Sie sich für ein kommerzielles Produkt (z. B. ein Spiel) entscheiden, müssen Sie damit rechnen, dass viele Benutzer Ihr Produkt möglicherweise nicht ausführen können.
  2. Normalerweise benötigen Sie zusätzliche Kenntnisse in GPU / CPU-Architektur , paralleler Programmierung und Multithreading (z. B. Speicherfreigabe, Speicherkohärenz, Thread-Synchronisation, Atomics und deren Auswirkungen auf die Leistung), die Sie normalerweise nicht für die Verwendung normaler Shader-Rounte benötigen.
  3. Lernressourcen : Erfahrungsgemäß gibt es für Compute Shadrs, OpenCL und CUDA (die auch OpenGL-Interoperabilität bieten) weitaus weniger Lernressourcen als für die übliche Shader-Route.
  4. Debugging-Tools Da das Debuggen nicht ordnungsgemäß ist, kann die Entwicklung von Tools viel schwieriger werden als bei den meisten Shadern. Zumindest können Shader visuell debuggt werden.
  5. Ich erwarte, dass Compute-Shader eine bessere Leistung bieten als der gleiche Algorithmus in anderen Shadern. wenn sie unter Berücksichtigung der Punkte von Punkt 2 richtig gemacht wurden , da sie die zusätzlichen Schritte für das Rendern von Grafiken vermeiden sollten. Ich habe jedoch keine konkreten Beweise für meine Behauptung.
  6. Sie sollten auch CUUDA / OpenCL für GPGPU in Betracht ziehen, wenn Sie diesen Weg gehen.

Trotzdem bin ich mir sicher, dass es großartig für die Zukunft ist und eine großartige Lernerfahrung sein wird. Viel Glück!

concept3d
quelle
Ich denke, das OP könnte folgende Frage stellen: Warum sollte ein Problem mit reinen GLSL-Shadern gelöst werden, anstatt es in CUDA zu codieren? Es gibt einen Artikel über Game Programming Gems über Stoffsimulationen, in dem der Autor genau das tut. Und der alte GLSL-Hacky-Weg ist in Bezug auf die Leistung besser als der CUDA-Weg. Sie sollten wahrscheinlich darauf hinweisen, warum, wenn Sie eine Idee haben, warum.
Teodron
2
Ich denke nicht, dass Ihr Skalierbarkeitspunkt korrekt ist - Vertex- und Fragment-Shader können genauso gut über die gesamte GPU skaliert werden wie Compute-Shader. Tatsächlich kann die Skalierung von Compute-Shadern schwieriger sein, da die Größe der Thread-Gruppe und die Nutzung des gemeinsam genutzten Speichers die Anzahl der gleichzeitig ausgeführten Shader-Threads zusätzlich einschränken können.
Nathan Reed
2
Wenn Sie eine Textur füllen (z. B. Rauschen erzeugen oder einen anderen prozeduralen Algorithmus ausführen), ist meiner Erfahrung nach ein Fragment-Shader schneller als ein Compute-Shader, wenn Sie einfach eine Formel für jedes Pixel auswerten. Ich vermute, dies liegt daran, dass die Fragmentreihenfolge mit der internen Reihenfolge der gekachelten / überstrichenen Pixel übereinstimmt, wodurch eine bessere Speicherlokalität erzielt wird als beim Compute-Shader, der diese Reihenfolge nicht kennt. Compute-Shader sind nur dann schneller, wenn Sie ihre speziellen Funktionen, z. B. den gemeinsam genutzten Speicher, verwenden können, um die Geschwindigkeit im Vergleich zu einem Fragment-Shader erheblich zu beschleunigen.
Nathan Reed
2
OK, letzter Kommentar. :) Ich denke, die meisten aktuellen GPUs haben eine Art Kontext- oder Moduswechsel, wenn sie von Grafik zu Computer wechseln und umgekehrt. Wenn Sie also einige Grafik-Shader ausführen, dann einen Compute-Shader senden, dann weitere Grafik-Shader usw. ausführen, treten beim Hin- und Herwechseln Leistungseinbußen auf. Das müssten Sie profilieren, aber es könnte in einem bestimmten Fall ein weiterer Grund sein, sich an Grafik-Shader zu halten.
Nathan Reed
@ NathanReed danke für die Kommentare Ich werde meine Antwort aktualisieren.
Konzept3d