Geometrische Transformationen auf der CPU gegen GPU
9
Ich habe festgestellt, dass viele 3D-Programme normalerweise Vektor- / Matrixberechnungen sowie geometrische Transformationen auf der CPU durchführen. Hat jemand einen Vorteil darin gefunden, diese Berechnungen in Vertex-Shader auf der GPU zu verschieben?
Generell: Mesh-Transformationen werden auf der GPU durchgeführt. Sie senden die Transformationsmatrix an die GPU und der Shader wendet sie auf alle Scheitelpunkte des Netzes an.
Die Verwendung der GPU zur Berechnung der Matrix selbst ist eine andere Sache und auf der GPU tatsächlich langsamer, da sich so viele gespeicherte Werte von Frame zu Frame ändern, die zur Bestimmung der endgültigen Transformationsmatrix erforderlich sind. Das Senden dieser Daten an und von der CPU - GPU ist langsam. Auf der CPU werden die Berechnungen auch einmal durchgeführt, während sie auf der GPU für jeden Scheitelpunkt durchgeführt werden.
Für den Teil "Eigentlich langsamer auf der GPU"; Dies ist eine sehr breite Aussage. Wenn Sie über die Erstellung der Matrix für jeden Scheitelpunkt auf der GPU sprechen, hängt Ihre Leistung von Ihren Engpässen ab. Sie erhalten nur dann eine langsamere Leistung, wenn Sie an die GPU ALU / Register gebunden sind, was nicht unbedingt der Fall ist. In diesen Engpassszenarien wäre es auch langsamer, auf einer CPU genau dasselbe zu tun. Ein Beispiel , wo dies wird häufig auf GPU getan: Vertex - Shader - Konstrukt Vertex Tangentialraumes Matrizen im Fluge um Bandbreite zu sparen Vertex zu holen. Wieder abhängig von Ihren Engpässen, also YMMV.
Jpaver
Ich kann nicht ablehnen, aber diese Antwort sollte abgelehnt werden. Es ist sehr falsch zu sagen "tatsächlich langsamer auf der GPU".
Adam
3
Viele geometrische Transformationen können auf Nicht-GPU-Prozessoren durchgeführt werden, man muss jedoch die Zielplattform berücksichtigen. Ihr Kilometerstand hängt von der Plattform ab, auf die Sie abzielen, und von den Engpässen dieser Plattform.
Eine Überlegung ist die Busbandbreite zwischen dem Gerät, das die Geometrie generiert, und dem Gerät, das die Geometrie rendert.
In einem typischen modernen PC-System befindet sich die CPU auf der einen Seite des PCIe-Busses (http://en.wikipedia.org/wiki/PCI_Express) und die GPU auf der anderen Seite. Die einzige Möglichkeit, pro Frame generierte Daten von der CPU zur GPU (und umgekehrt) zu übertragen, besteht über diesen Bus. Dies bedeutet, dass Sie durch die Übertragungsgeschwindigkeit dieses Busses eingeschränkt werden können. Wenn Ihre Zielplattform über PCIe 2.x mit 16 Lanes verfügt, haben Sie eine Bandbreite von 8 GB / s. In der Praxis sind Übertragungen über die PCIe nicht 100% effizient, da ein Teil der Bandbreite für das Protokoll während Ihrer Übertragungen verbraucht wird. Abhängig von der Größe Ihrer Übertragungen können Sie 5-10% Ihrer Bandbreite allein durch den Overhead pro Paket verlieren.
z.B. Wie viele Daten können Sie bei einer PC-Plattform, auf der PCIe 2.x mit 16 Lanes ausgeführt wird, pro Frame für die Einspeisung in die GPU generieren? Angenommen, Sie möchten den Lauf mit 60 fps ausführen, bedeutet dies 8 GB / 60 = 136 MB pro Frame für PCIe 2.x. Durch Multiplikation mit einem (gastimierten) 90% -Faktor zur Berücksichtigung des Overheads der Treiberkommunikation und des Overheads des PCIe-Übertragungsprotokolls können Sie pro Frame etwa 120 MB Daten generieren, ohne durch die PCIe 2.x-Bandbreite eingeschränkt zu sein.
Eine weitere Frage, die Sie beantworten müssen: Wird die Generierung dieser 120 MB Daten auf Ihrer Ziel-CPU in 1/60 Sekunde problemlos möglich sein? Wenn Sie sich daran erinnern, dass Sie eine Reihe anderer Spielaufgaben auf Ihrer CPU ausführen müssen, kann es zu Zeitmangel kommen, um die transformierten Daten zu generieren. In Bezug auf den reinen ALU-Durchsatz kann dies die CPU einschränken. In Bezug auf CPU-zu-System-Busse können Sie auch durch die Bandbreite begrenzt werden (die variiert, bei neueren CPUs jedoch bei ~ 8,5 GB / s liegt).
Okay, welche Faktoren machen es dann praktikabler, auf einer GPU zu arbeiten? Ein Faktor ist die GPU-Speicherbandbreite, dh die Bandbreite zwischen der GPU und ihrem lokalen Videospeicher. Bei modernen GPUs der mittleren Preisklasse kann diese Videospeicherbandbreite bis zu 200 GB / s betragen (ja, das ist das 25-fache der PCIe 2.x-Bandbreite). Ein weiterer Faktor ist, dass die GPU massiv parallel ist, Hunderte von ALUs hat und in der Lage ist, die Speicherzugriffslatenz zu verbergen, indem Tausende von Threads gleichzeitig ausgeführt werden.
All diese Faktoren können zu dem offensichtlichen Gewinn beitragen, mehr Arbeit auf die GPU zu übertragen, aber wiederum YMMV, abhängig von Ihrer Zielplattform.
Was meinst du mit "Mesh-Transformationen"? Geometrie durch einen Satz von Matrizen transformieren? Bei den meisten Spielen dieser Tage kann die GPU einfache Transformationen, Skins usw. ausführen. Die meisten von ihnen verwenden dafür Vertex-Shader. Auf einigen Plattformen haben Sie entweder keine Shader oder es gibt andere Vorteile, wenn Sie diese Dinge auf der CPU ausführen. Auf der PS3 können Sie beispielsweise den RSX entlasten, indem Sie die SPUs das Skinnen und Transformieren übernehmen lassen. Wenn Sie eine Beleuchtung mit mehreren Durchgängen ausführen, kann das Enthäuten auf der CPU von Vorteil sein, da Sie dies nur einmal tun und die zu zeichnenden Ergebnisse für jeden Rendering-Durchgang senden müssen. Es gibt also Ausnahmen, aber im Allgemeinen machen die meisten Spiele diese Dinge auf der GPU und in Shadern.
Oder meinten Sie etwas ausgefalleneres, wie die Verwendung der GPU für die allgemeine Vektormathematik? Heutzutage haben wir Allzweck-GPUs, die ziemlich generischen C-Code über Systeme wie CUDA ausführen können. Es ist möglich, dies für schwere Vektormathematik zu nutzen, und ich weiß, dass es Programme gibt, die dies tun. Ich persönlich habe jedoch keine Erfahrung damit.
"Netztransformation" wurde in "geometrische Transformation" geändert, um die Frage zu klären. Ich warte auch auf offene Stellen, die bereits im nächsten Jahr verfügbar sein könnten.
Zmdat
0
Es gibt Situationen, in denen es möglicherweise sinnvoll ist, alles auf der GPU zu rendern, aber Sie können keine Konstanten in einem Shader festlegen, und es gibt wirklich keinen anderen Ort, an dem Sie sie einrichten können, außer auf der CPU-Seite vor einem Draw-Aufruf.
Selbst wenn Sie Ihre Konstanten wie die Knochentransformationsmatrizen auf der GPU mit einem benutzerdefinierten Initialisierungsprogramm berechnen könnten, würden Sie dies wahrscheinlich nicht wollen. Die GPU ist wirklich gut in der parallelen Ausführung, hat aber eine viel langsamere Taktrate.
Das Transformieren einer Hierarchie ist nicht trivial parallelisierbar, da die untergeordneten Knoten von den übergeordneten Knoten abhängen, das Transformieren aller Scheitelpunkte in einem Netz jedoch, da die Scheitelpunkte rechnerunabhängig voneinander sind.
Viele geometrische Transformationen können auf Nicht-GPU-Prozessoren durchgeführt werden, man muss jedoch die Zielplattform berücksichtigen. Ihr Kilometerstand hängt von der Plattform ab, auf die Sie abzielen, und von den Engpässen dieser Plattform.
Eine Überlegung ist die Busbandbreite zwischen dem Gerät, das die Geometrie generiert, und dem Gerät, das die Geometrie rendert.
In einem typischen modernen PC-System befindet sich die CPU auf der einen Seite des PCIe-Busses (http://en.wikipedia.org/wiki/PCI_Express) und die GPU auf der anderen Seite. Die einzige Möglichkeit, pro Frame generierte Daten von der CPU zur GPU (und umgekehrt) zu übertragen, besteht über diesen Bus. Dies bedeutet, dass Sie durch die Übertragungsgeschwindigkeit dieses Busses eingeschränkt werden können. Wenn Ihre Zielplattform über PCIe 2.x mit 16 Lanes verfügt, haben Sie eine Bandbreite von 8 GB / s. In der Praxis sind Übertragungen über die PCIe nicht 100% effizient, da ein Teil der Bandbreite für das Protokoll während Ihrer Übertragungen verbraucht wird. Abhängig von der Größe Ihrer Übertragungen können Sie 5-10% Ihrer Bandbreite allein durch den Overhead pro Paket verlieren.
z.B. Wie viele Daten können Sie bei einer PC-Plattform, auf der PCIe 2.x mit 16 Lanes ausgeführt wird, pro Frame für die Einspeisung in die GPU generieren? Angenommen, Sie möchten den Lauf mit 60 fps ausführen, bedeutet dies 8 GB / 60 = 136 MB pro Frame für PCIe 2.x. Durch Multiplikation mit einem (gastimierten) 90% -Faktor zur Berücksichtigung des Overheads der Treiberkommunikation und des Overheads des PCIe-Übertragungsprotokolls können Sie pro Frame etwa 120 MB Daten generieren, ohne durch die PCIe 2.x-Bandbreite eingeschränkt zu sein.
Eine weitere Frage, die Sie beantworten müssen: Wird die Generierung dieser 120 MB Daten auf Ihrer Ziel-CPU in 1/60 Sekunde problemlos möglich sein? Wenn Sie sich daran erinnern, dass Sie eine Reihe anderer Spielaufgaben auf Ihrer CPU ausführen müssen, kann es zu Zeitmangel kommen, um die transformierten Daten zu generieren. In Bezug auf den reinen ALU-Durchsatz kann dies die CPU einschränken. In Bezug auf CPU-zu-System-Busse können Sie auch durch die Bandbreite begrenzt werden (die variiert, bei neueren CPUs jedoch bei ~ 8,5 GB / s liegt).
Okay, welche Faktoren machen es dann praktikabler, auf einer GPU zu arbeiten? Ein Faktor ist die GPU-Speicherbandbreite, dh die Bandbreite zwischen der GPU und ihrem lokalen Videospeicher. Bei modernen GPUs der mittleren Preisklasse kann diese Videospeicherbandbreite bis zu 200 GB / s betragen (ja, das ist das 25-fache der PCIe 2.x-Bandbreite). Ein weiterer Faktor ist, dass die GPU massiv parallel ist, Hunderte von ALUs hat und in der Lage ist, die Speicherzugriffslatenz zu verbergen, indem Tausende von Threads gleichzeitig ausgeführt werden.
All diese Faktoren können zu dem offensichtlichen Gewinn beitragen, mehr Arbeit auf die GPU zu übertragen, aber wiederum YMMV, abhängig von Ihrer Zielplattform.
quelle
Was meinst du mit "Mesh-Transformationen"? Geometrie durch einen Satz von Matrizen transformieren? Bei den meisten Spielen dieser Tage kann die GPU einfache Transformationen, Skins usw. ausführen. Die meisten von ihnen verwenden dafür Vertex-Shader. Auf einigen Plattformen haben Sie entweder keine Shader oder es gibt andere Vorteile, wenn Sie diese Dinge auf der CPU ausführen. Auf der PS3 können Sie beispielsweise den RSX entlasten, indem Sie die SPUs das Skinnen und Transformieren übernehmen lassen. Wenn Sie eine Beleuchtung mit mehreren Durchgängen ausführen, kann das Enthäuten auf der CPU von Vorteil sein, da Sie dies nur einmal tun und die zu zeichnenden Ergebnisse für jeden Rendering-Durchgang senden müssen. Es gibt also Ausnahmen, aber im Allgemeinen machen die meisten Spiele diese Dinge auf der GPU und in Shadern.
Oder meinten Sie etwas ausgefalleneres, wie die Verwendung der GPU für die allgemeine Vektormathematik? Heutzutage haben wir Allzweck-GPUs, die ziemlich generischen C-Code über Systeme wie CUDA ausführen können. Es ist möglich, dies für schwere Vektormathematik zu nutzen, und ich weiß, dass es Programme gibt, die dies tun. Ich persönlich habe jedoch keine Erfahrung damit.
quelle
Es gibt Situationen, in denen es möglicherweise sinnvoll ist, alles auf der GPU zu rendern, aber Sie können keine Konstanten in einem Shader festlegen, und es gibt wirklich keinen anderen Ort, an dem Sie sie einrichten können, außer auf der CPU-Seite vor einem Draw-Aufruf.
Selbst wenn Sie Ihre Konstanten wie die Knochentransformationsmatrizen auf der GPU mit einem benutzerdefinierten Initialisierungsprogramm berechnen könnten, würden Sie dies wahrscheinlich nicht wollen. Die GPU ist wirklich gut in der parallelen Ausführung, hat aber eine viel langsamere Taktrate.
Das Transformieren einer Hierarchie ist nicht trivial parallelisierbar, da die untergeordneten Knoten von den übergeordneten Knoten abhängen, das Transformieren aller Scheitelpunkte in einem Netz jedoch, da die Scheitelpunkte rechnerunabhängig voneinander sind.
Die allgemeine Regel lautet:
quelle