TEST

Grafikkarten-FAQ 2023

Was man über Grafikkarten wissen sollte - Die GPU

Portrait des Authors


Werbung

In Kooperation mit Zotac

Was ist eine Shadereinheit oder ein CUDA-Core?

CUDA-Core, Streamprozessor, Shadereinheit – dies alles und noch einige Begriffe mehr sind Synonyme für die Recheneinheiten in einer GPU, die sich um die eigentliche Berechnung der Daten kümmern. NVIDIA selbst beschreibt diese als CUDA-Kerne, wobei CUDA für Compute Unified Device Architecture steht. Die CUDA-Kerne sind aber nicht mit den Kernen eines Prozessors vergleichbar, da sie weit weniger komplex aufgebaut sind und auf eine sehr spezielle Art und Weise der Datenverarbeitung spezialisiert sind. Da GPUs inzwischen aber mehr leisten können, als über eine Shaderpipeline eine Grafik zu rendern, ist eine Vereinheitlichung der Begrifflichkeiten zu einem übergeordneten Namen wie Streamprozessor oder Unified Shader trefflich gewählt.

Der Begriff Streamprozessor trifft die Aufgabe ganz gut, denn es geht darum, Datenströme zu verarbeiten, die stetig anfallen und die sich auch sehr gut parallelisieren lassen. Inzwischen sprechen wir von mehreren tausend Shadereinheiten pro GPU und ebenso wie das Rendern einer Grafik sich gut parallelisieren lässt, ist dies auch für wissenschaftliche Berechnungen der Fall. Das hat GPUs im Serverbereich als Rechenbeschleuniger zum Durchbruch verholfen.

Ein Shader beschreibt aber nicht die eigentliche Hardware bzw. hier müssen Unterscheidungen gemacht werden. Im Falle moderner GPUs sind die Recheneinheiten auf Fließkomma- (Floating Point oder kurz FP) und Integer-Berechnungen (ganzzahlige Berechnungen abgekürzt mit INT) unterschiedlichster Komplexität ausgelegt. Typischerweise sind FP32- und INT32-Berechnungen, also Rechenoperationen mit einer Genauigkeit von 32 Bit für das Rendering einer Grafik am wichtigsten. Für den wissenschaftlichen Bereich immer wichtiger aber werden die höheren Genauigkeiten mit FP64 und auch dafür gibt es dedizierte Recheneinheiten in einer GPU. Neuerdings hat man allerdings erkannt, dass 32 und 64 Bit längst nicht überall notwendig sind. Um eine INT32-Recheneinheit nicht mit einer weniger komplexen Berechnung zu belegen, wurden Verfahren entwickelt, eine INT32-Rechenheit mit zweimal 16 Bit Integer-Berechnungen zu nutzen, die gleichzeitig ausgeführt werden können.

Noch einen Schritt weiter geht die Integration der Tensor Cores der Ampere-Architektur von NVIDIA, die auf noch weniger komplexe Berechnungen in INT8 und INT4 ausgelegt sind, dazu aber später mehr.

Anhand der Ada-Lovelace-Architektur wollen wir uns den Aufbau der Recheneinheiten anschauen, denn es befinden sich nicht einfach nur mehrere tausend Shadereinheiten auf der GPU, sondern diese sind in einer bestimmten Form organisiert.

Die AD102-GPU verfügt über 12 GPCs (Graphics Processing Clusters) mit jeweils 12 SMs. Bei der GeForce RTX 4090 und GeForce RTX 4080 sind aber nicht alle SMs aktiviert. Die AD102-GPU käme theoretisch auf insgesamt 18.432 FP32-Einheiten (12 GPCs x 12 SMs x 128 FP32-Einheiten). Für die GeForce RTX 4090 aber insgesamt 16 SMs deaktiviert worden und somit kommt die Karte auf "nur" 16.384 FP32-Einheiten. NVIDIA tut dies, um die Ausbeute der Chips so hoch wie möglich zu halten.

Für die GeForce RTX 4080 kommt bereits die kleinere AD103-GPU zum Einsatz, die über 8 SMs insgesamt verfügt, von denen 6 aktiv sind und somit kommen wir hier auf 9.728 Shadereinheiten. Eine AD104-GPU kommt für die GeForce RTX 4070 Ti und GeForce RTX 4070 zum Einsatz. Darunter positioniert NVIDIA noch eine AD106- und AD107-GPU, die für die Modelle der GeForce RTX 4060 (Ti) verwendet wird. Das es sich bei diesen beiden im Notebook-GPUs handelt sieht man auch daran, dass hier das PCI-Express-Interface auf acht Lanes reduziert wurde.

Integer- und Fließkomma-Berechnungen gleichzeitig ausführen

Wie bereits erwähnt kann eine FP32-Recheneinheit auch 2x FP16 ausführen und gleiches gilt auch für INT16. Um die Rechenleistung flexibler zu machen und diese insgesamt anzuheben, hat NVIDIA mit der Turing-Architektur eine gleichzeitige Berechnung von Fließkomma- und Integer-Datensätzen ermöglicht. Dies setzte man auch für die Ampere- und Ada-Lovelace-Architektur fort. Dazu hat sich NVIDIA die Ausführung dieser Berechnungen in der Rendering-Pipeline anhand dutzender Spiele angeschaut und konnte dabei feststellen, dass pro 100 FP-Berechnungen etwa ein Drittel an INT-Berechnungen anfallen. Dies entspricht einem Mittelwert, der allerdings auch von 20 % bis 50 % schwanken kann. Ist es nicht möglich, FP- und INT-Berechnungen gleichzeitig auszuführen, gibt es hier gewisse Abhängigkeiten, die zu Verzögerungen in der Rendering-Pipeline führen können.

Das Verhältnis aus 1/3 INT32 und 2/3 FP32 zeigt sich auch in der Auslegung des Ada Lovelace Streaming Multiprocessor (SM) als Basisbaustein der Ada-Lovelace-Architektur. Hier wurde die Anzahl der FP32-Recheneinheiten pro SM verdoppelt. Statt 64 der FP32-Einheiten pro SM gibt es nun 128. Hinzu kommen 64 INT32-Einheiten. Es gibt nun zwei Datenpfade pro Quadrant eines SMs, die teilweise parallel angesprochen werden können. Einer der Datenpfade besteht aus 16 FP32-Einheiten. Hier können also 16 FP32-Berechnungen pro Takt bearbeitet werden. Ein zweiter Datenpfad besteht aus jeweils 16 FP32- und INT32-Einheiten. Jeder der SM-Quadranten kann entweder 32 FP32-Operationen ausführen oder jeweils 16 FP32- und INT32-Operationen pro Takt. Für den gesamten SM bedeutet dies die mögliche Ausführung von 128 FP32-Operationen oder jeweils 64 FP32- und INT32-Operationen pro Takt.

Die gleichzeitige Ausführung mehrere Einheiten setzt sich aber auch an anderer Stelle fort. So arbeiten auch die RT und Tensor Cores parallel in der Render-Pipeline und somit wird die Gesamtzeit verkürzt, die für ein Rendering eines Frames notwendig ist.

Shadereinheiten sind also keine mysteriöse Größe mehr, sondern beschreiben einfach vielmehr die Anzahl der Rechenheiten in der GPU, wenngleich man zwischen verschiedenen Komplexitäten der Rechenkapazitäten unterscheiden sollte. Die Begrifflichkeiten können unterschiedlich gewählt werden, meinen aber meist ein und die gleiche Größe zur Beschreibung der Recheneinheiten in einer GPU.

Textureinheiten

In den Shadereinheiten werden sogenannte Shader vorprogrammiert, die dann wiederum die Berechnung bestimmter Werte vornehmen. So können Vertex-Shader dazu verwendet werden, geometrischen Berechnungen und dynamischen Veränderungen von Objekten vorzunehmen. Die Geometry-Shader wiederum berechnen aus den Punkten, Linien und Dreiecken die letztendliche Geometrie und den Aufbau der Objekte und es gibt auch noch Tessellation-Shader, die sogenannten Primitives (zum Beispiel Dreiecke) weiter unterteilen können.

Die Textureinheiten oder Texture Mapping Units (TMU) sind dafür verantwortlich, dass alle Flächen auch mit den dazugehörigen Texturen belegt werden. Die Textureinheiten sind dedizierte Recheneinheiten in einer GPU. Im Falle der Ada-Lovelace-Architektur kommt auf 16 Shadereinheiten eine Textureinheit. Die für eine Textureinheit notwendigen Daten liegen im Grafikspeicher und können von dort gelesen und in den Speicher geschrieben werden. Da die Textureinheiten inzwischen nicht mehr externe Recheneinheiten im eigentlichen Sinne, sondern Bestandteil der Grafikpipeline sind, können Objekte auch mehrfach von der Textureinheit verwendet werden. 

Für das Rendering eines Objekts reicht eine Textur längst nicht mehr aus, sondern es gibt mehrere Ebenen, die beispielsweise eine gewisse 3D-Optik einer eigentlichen flachen Textur erstellen können. Während das Objekt früher mehrfach berechnet und jeweils von der Textureinheit mit der jeweiligen Textur belegt wurde, reicht heute ein Renderprozess, auf den die Textureinheit aus einem Buffer heraus mehrfach auf dieses Objekt zugreifen kann.

Speichercontroller

Eine möglichst hohe Speicherbandbreite ist ebenso wichtig wie die Rechenleistung der GPU selbst. Nur wenn die Daten auch schnell vom Grafikspeicher an die GPU geliefert und darin wieder geschrieben werden können, können die Berechnungen auch entsprechend schnell durchgeführt werden. Man spricht hier gerne vom Backend in Form der Rechenleistung der GPU und dem Frontend in Form der Cache-Hierarchie und der Anbindung des Speichers. Jede GPU-Architektur wird entsprechend ausgelegt, profitiert mal von einer hohen Speicherbandbreite und ist mal nicht so sehr davon abhängig. Davon abgesehen, sind natürlich alle Hersteller darauf aus, eine möglichst hohe Speicherbandbreite zu erreichen. Dabei spielt der Speichercontroller eine entscheidende Rolle.

Neben den Änderungen in den SMs gibt es auch solche im Aufbau der ROPs bzw. der Kopplung zwischen den ROPs und den Speichercontrollern. Bis zur Turing-Generation sind die ROPs immer am Speicherinterface angeschlossen. Pro 32-Bit-Speichercontroller waren acht ROPs vorhanden. Änderte sich die Anzahl der Speichercontroller und damit die Größe des Speicherinterface, galt dies auch für die ROPs. Für die Ada-Lovelace-Architektur sind die ROPs im GPC untergebracht. Pro GPC gibt es zwei ROP-Partitionen, die jeweils acht ROPs enthalten. 

Damit ergibt sich auch eine andere Berechnung für die Anzahl der ROPs bei der GeForce RTX 4090. Wir sprechen hier von 12 GPCs mit jeweils 2x 8 ROPs also 176 ROPs ingesamt. Für die GeForce RTX 4080 sind es sieben GPCs mit 2x 8 ROPs und dementsprechend 112 ROPs. NVIDIA hat die Integration der ROPs in dieser Form ausgeführt, um das Render-Backend nicht mehr derart abhängig vom Speicherinterface zu machen. So hat man nun zwar ein 256 Bit breites Speicherinterface für die GeForce RTX 4080 umgesetzt, kann aber 112 anstatt nur 80 ROPs verwenden.

Das Speicherinterface ist weiterhin in 32-Bit-Blöcken aufgeteilt. Je nach gewünschter Breite des Speicherinterfaces oder der Speicherkapazität die zum Einsatz kommen soll, kann hier in diesen Schritten gewählt werden.

L1- und L2-Caches

Der L1-Cache ist für vier SMs 128 kB groß. Der L2-Cache wird aber deutlich größer. So besitzt die volle AD102-GPU einen L2-Cache mit einer Kapazität von 98.304 kB – also fast 100 MB. In der Ausbaustufe der GeForce RTX 4090 kommt die GPU auf 73.728 kB. Bei der GA102-GPU waren nur 6.144 kB an L2-Cache vorhanden. NVIDIA setzt also auf einen um den Faktor 12 größeren L2-Cache und erhofft sich damit sicherlich weniger Engpässe im Zugriff auf den Grafikspeicher.

RT-Cores der 3. Generation

Die Raytracing-Einheiten oder RT-Cores der 3. Generation von Ada haben einen doppelt so hohen Durchsatz an ihren Recheneinheiten wie ihre Vorgänger, wodurch die Raytracing-Rechenleistung um bis zu 2,8x gesteigert wird. Für die GeForce RTX 4090 bedeutet dies theoretisch 191 RT-TFLOPS, verglichen mit 78 RT-TFLOPS bei der GeForce RTX 3090 Ti.

Zudem bieten die RT-Cores der 3. Generation Funktionen wie die Opacity Micro-Map-Engines und Micro-Mesh-Engines. Dies sind neue, spezielle Hardwareeinheiten zur Beschleunigung besonders anspruchsvoller Raytracing-Workloads, die dann per Software angesprochen werden können.

Die Opacity Micro-Maps und Displaced Micro-Meshes wollen wir aber noch etwas genauer erläutern

Die Opacity-Micro-Maps sind eine Form der Optimierung für das Raytracing. Darstellungsdetails werden vordefiniert auf die Objekte der Spiele-Welt kodieren. Ein Raytracing kann für bestimmte Objekte extrem komplex sein. Laub und Vegetation im Allgemeinen sind solche Beispiele. Solche Objekte sind für die zu berechnenden Strahlen schwierig, da es unzählige Richtungen gibt, in die zwischen Blättern und Ästen reflektiert werden kann. Die RT-Cores der dritten Generation verwendet Opacity-Micro-Maps, um den Opazitätsstatus dieser Elemente zuzuweisen, der undurchsichtig, transparent oder unbekannt sein kann.

Komplexen Objekte wurden bisher gar nicht oder nur ungern mit Raytracing-Effekten belegt. Die Opacity Micro-Maps sollen dies nun ermöglichen.

Die Displaced Micro-Meshes (DMM) werden ebenfalls durch die RT-Cores der dritten Generation generiert. Die für die Raytracing-Berechnungen verwendeten Bounding Volume Hierarchies (BVH) sollen damit 10-mal schneller aufgebaut werden können und 20-mal weniger Grafikspeicher benötigen. NVIDIA beschreibt die DMMs wie folgt: "DMMs sind neue Primitive, die ein strukturiertes Netz aus Mikrodreiecken darstellen, das die RT-Recheneinheiten der 3. Generation nativ verarbeiten. Dadurch werden die Speicher- und Verarbeitungsanforderungen beim Rendern komplexer Geometrien, die nur einfache Dreiecke verwenden, im Vergleich zu früheren Generationen reduziert."

Tensor-Cores der 4. Generation und DLSS 3

Auch das Deep Learning Super Sampling bekommt ein Update und soll in Version drei weiter verbessert worden sein. Hier kommen auch die ebenfalls verbesserten Tensor-Cores der 4. Generation zum Einsatz. Für FP8-Berechnungen haben die neuen Tensor-Cores einen bis zu 5-Fach höheren Durchsatz.

Sogenannte Optical-Flow-Beschleuniger kommen dann für DLSS 3 zum Einsatz. Sie berechnen Pixelbewegungsdaten aus nachfolgenden Frames für das neuronale Netzwerk von DLSS. Dazu kommen wir im Zusammenhang von DLSS 3 und Ray Reconstruction sowie der Frame Generation aber noch.

Shader Execution Reordering

Mittels Shader Execution Reordering (SER) werden die Berechnungen in der Pipeline effizient zusammengeführt, sodass die Recheneinheiten immer möglichst hoch ausgelastet sind. Dies soll die Shaderleistung um das bis zu 2-Fache verbessern und die Frameraten im Spiel um bis zu 25 % steigern.

In Kooperation mit Zotac