Moderne GPUs: Wie „intelligent“ sind sie?

11

Es gibt viele Ressourcen zur 3D-Programmierung (OpenGL oder DirectX) und den entsprechenden Grafik-Pipelines, aber ich frage mich, auf welcher Ebene sie auf einer modernen GPU implementiert sind.

Bisher konnte ich feststellen, dass es einen Übergang von einer sehr spezialisierten Schaltung, die die verschiedenen Phasen der Grafikpipeline implementiert, zu einem allgemeineren Ansatz gegeben hat. Diese Transformation wurde teilweise in Form von programmierbaren Shadern auf den 3D-APIs reflektiert. Die meisten Transistoren scheinen für massiv parallele SIMD-Einheiten vorgesehen zu sein, die die eigentlichen Shader-Anweisungen ausführen.

Aber was ist mit dem Rest der Grafik-Pipeline? Ist das noch in Hardware implementiert?

Ist eine moderne GPU (denken Sie an Nvidia Fermi) im Grunde eine Reihe von "dummen" SIMD-Arrays, die mit Anweisungen und Daten von der CPU und verschiedenen Caches gespeist werden, und die gesamte tatsächliche Logik, die die Grafikpipeline diesen Anweisungen zuordnet, findet im Grafiktreiber statt ?

Oder gibt es irgendwo in der GPU einige Steuereinheiten, die die eingehenden übergeordneten Befehls- und Datenströme (kompilierte Shader-Programme, Scheitelpunktdaten und -attribute sowie Texturen) in tatsächliche SIMD-Befehle übersetzen und sich um Synchronisation, Speicherzuweisung usw. kümmern?

Ich vermute, dass die Realität irgendwo zwischen diesen beiden Extremen liegt, und die Antwort wäre ziemlich langwierig und basiert auf vielen Spekulationen (es muss einen Grund dafür geben, dass bestimmte GPU-Anbieter sich weigern, Dokumentationen zu ihren Produkten zu veröffentlichen, geschweige denn Treiber Quellcode ...), aber alle Hinweise in die richtige Richtung und nützliche Ressourcen wären sehr dankbar.

Bisher habe ich eine Reihe von Blog-Posts gefunden , die sehr hilfreich waren, um mehr über moderne GPUs zu erfahren, aber mir fehlt eine übergeordnete Übersicht über die Gesamtarchitektur - ich kann die meisten der genannten Konzepte verstehen, aber verstehe nicht ganz, wie sie zusammenpassen.

lxgr
quelle

Antworten:

8

Bisher konnte ich feststellen, dass es einen Übergang von einer sehr spezialisierten Schaltung, die die verschiedenen Phasen der Grafikpipeline implementiert, zu einem allgemeineren Ansatz gegeben hat. Diese Transformation wurde teilweise in Form von programmierbaren Shadern auf den 3D-APIs reflektiert. Die meisten Transistoren scheinen für massiv parallele SIMD-Einheiten vorgesehen zu sein, die die eigentlichen Shader-Anweisungen ausführen.

Richtig. Aufgrund der relativ großen Feature-Größe älterer GPUs bestand die einzige Möglichkeit, Dinge wie Grundbeleuchtung, Antialiasing, Texturabbildung, Geometrie usw. effizient zu implementieren, in der Verwendung einer Pipeline mit "festen Funktionen". Sie haben aus Gründen der Leistung auf Flexibilität verzichtet, weil sie nicht über genügend Chipdichte verfügten, um sie mit einer allgemeineren, massiv parallelen SIMD-Architektur wie aktuellen GPUs implementieren zu können.

Ist eine moderne GPU (denken Sie an Nvidia Fermi) im Grunde eine Reihe von "dummen" SIMD-Arrays, die mit Anweisungen und Daten von der CPU und verschiedenen Caches gespeist werden, und die gesamte tatsächliche Logik, die die Grafikpipeline diesen Anweisungen zuordnet, findet im Grafiktreiber statt ?

Bestimmte Dinge werden immer noch in Hardware erledigt; andere nicht. Beispielsweise werden ROPs noch in der letzten Phase verwendet, um Pixeldaten in den VGA-Chipsatz zu übertragen. Hinweis: Ich verwende hier "VGA-Chipsatz" als Oberbegriff für den Mechanismus, der ein Videosignal an Ihren Monitor überträgt, unabhängig davon, ob es sich in irgendeiner Hinsicht wirklich um "VGA" handelt.

Es ist im Allgemeinen richtig, dass aktuelle GPU-Architekturen wie Nvidia Fermi und AMD Southern Islands größtenteils massiv parallele CPUs sind, auf denen sie einen benutzerdefinierten Befehlssatz haben und jeder einzelne "Kern" extrem schwach ist, aber es gibt eine ganze Menge Kerne (manchmal mehrere Tausend). Aber es gibt immer noch grafikspezifische Hardware:

  • Hardware-Videodecodierung wird häufig größtenteils mit Chips mit festen Funktionen durchgeführt. Dies gilt insbesondere dann, wenn DRM (Digital Restrictions Management) beteiligt ist. Manchmal bedeutet "Hardware" -Videodecodierung wirklich einen Firmware-gesteuerten Satz von Anweisungen, die nur als normale alte Aufgaben für die SIMD-Kerne dienen. Es kommt wirklich darauf an.

  • Mit Ausnahme einiger weniger rechenspezifischer Nvidia-Karten (Tesla) verfügen fast alle "generischen SIMD" -Grafikkarten über eine komplette Hardware für die Videoausgabe. Die Videoausgabe ist nicht dasselbe wie das Rendern. Zu den Ausgangselementen mit festen Funktionen gehören LVDS / TMDS / HDMI / DisplayPort-Codecs, HDCP und sogar Audioverarbeitung (im Grunde ein wenig DSP), da HDMI Audio unterstützt.

  • "Grafikspeicher" wird weiterhin an Bord der GPUs gespeichert, sodass sie nicht den gesprächigen PCIe-Bus mit relativ hoher Latenz durchlaufen müssen, um den System-RAM zu erreichen, der selbst langsamer ist und länger als die teureren reagiert. Höherer Grafikspeicher mit höherer Qualität (z. B. GDDR5) mit geringerer Kapazität, aber höheren Geschwindigkeiten als der Systemspeicher. Das Speichern und Abrufen von Daten im Grafikspeicher von dort zur GPU oder zur CPU ist nach wie vor eine feste Funktionsoperation. Einige GPUs haben ihre eigene Art von "IOMMU", aber diese Speicherverwaltungseinheit unterscheidet sich von der CPU. Dies gilt jedoch nicht für neuere Intel-GPUs, die in ihre Prozessoren integriert sind (Sandy und Ivy Bridge), bei denen die Speicherarchitektur fast vollständig "kohärent" ist Systemspeicher) und Lesevorgänge aus dem Grafikspeicher sind für die CPU genauso günstig wie für die GPU.

Oder gibt es irgendwo in der GPU einige Steuereinheiten, die die eingehenden übergeordneten Befehls- und Datenströme (kompilierte Shader-Programme, Scheitelpunktdaten und -attribute sowie Texturen) in tatsächliche SIMD-Befehle übersetzen und sich um Synchronisation, Speicherzuweisung usw. kümmern?

Die "Muttersprache" der SIMDs wird fast immer vom Treiber in der Software und nicht von der GPU-eigenen Firmware generiert. Dies gilt insbesondere für DirectX 9 / OpenGL 2.x-Funktionen. Shader, die in Hochsprachen wie HLSL, GLSL oder OpenGL ARB Shader Assembler geschrieben sind, werden vom Treiber schließlich in GPU-Anweisungen übersetzt, indem auf bestimmte Register geklopft und die erforderlichen PCIe-Hoops ausgeführt werden, um Stapelpuffer für die Berechnung und / oder das Rendern zu senden Befehle.

Einige Dinge, wie die Hardware-Tessellation (DirectX 11 / OpenGL 4.0), werden wieder mit fester Funktion in die Hardware integriert, ähnlich wie früher fast alles. Dies liegt wiederum daran, dass Leistungsbeschränkungen erfordern, dass der effizienteste Weg, diese Berechnungen durchzuführen, darin besteht, dedizierte Schaltkreise dafür zu haben, anstatt dass die Firmware oder der Treiber die SIMDs "programmieren", um dies zu tun.

Ich vermute, dass die Realität irgendwo zwischen diesen beiden Extremen liegt, und die Antwort wäre ziemlich langwierig und basiert auf vielen Spekulationen (es muss einen Grund dafür geben, dass bestimmte GPU-Anbieter sich weigern, Dokumentationen zu ihren Produkten zu veröffentlichen, geschweige denn Treiber Quellcode ...), aber alle Hinweise in die richtige Richtung und nützliche Ressourcen wären sehr dankbar.

AMD und Intel haben eine sehr robuste Dokumentation über ihre jüngsten GPUs sowie voll funktionsfähige Open-Source-Grafiktreiber für Linux veröffentlicht (siehe die Projekte Mesa und Direct Rendering Manager). Wenn Sie einen Teil des Codes in diesen Treibern anschauen, werden Sie lachen, weil die Grafiktreiber Autoren haben tatsächlich zu implementieren , die Geometrie der Dinge wie verschiedene Formen oder Muster zeichnen, in der „Software“ (aber Hardware-Befehle mit der realen einreichen Beinarbeit an der Hardware für die Verarbeitung), da weder die GPU-Firmware noch das Zeug mit festen Funktionen mehr vorhanden sind, um es vollständig in der Hardware zu verarbeiten :) Es ist irgendwie lustig, was sie tun müssen, um OpenGL 1.x / 2.x auf neu zu unterstützen Hardware.

Die Evolution ist so verlaufen:

  • Vor sehr langer Zeit (bevor Echtzeit-3D-Rendering für möglich gehalten wurde): Raytracing auf der CPU war für Nicht-Echtzeit-Rendering normal. Für einfache Grafiken, wie Sie sie in früheren Windows-Versionen sehen, war die CPU schnell genug, um einfache Formen (Rechtecke, Zeichen einer Schriftart, Schattierungsmuster usw.) ohne Hardware mit festen Funktionen zu zeichnen, aber sie konnte nicht zu komplexe Inhalte zeichnen.
  • Vor langer Zeit (OpenGL 1.x): Fast alles, was mit Solid-State-Hardware implementiert wurde; "elektrisch" feste Funktionen waren selbst bei Grundoperationen die Norm
  • Vor einiger Zeit (OpenGL 2.x): Ein Übergang zur Programmierbarkeit von GPUs hatte begonnen. "Fragment Shader" (auch bekannt als Pixel Shader) auf 5 Jahre alter Hardware können fast beliebige Berechnungen wie eine CPU durchführen, sind jedoch durch die Architektur begrenzt, die immer noch stark auf Grafiken ausgerichtet ist. Daher sind OpenCL / DirectCompute auf dieser Hardware nicht verfügbar.
  • Kürzlich (OpenGL 3.x): Der Übergang zu Allzweck-GPUs ist größtenteils abgeschlossen, aber sie sind natürlich für Workloads optimiert, bei denen große Datenmatrizen (Think Linear Algebra) stapelweise übermittelt werden, anstatt CPUs, die effizient arbeiten können lange Sequenzen sehr kleiner Daten (1 + 1, 2 * 4, 5 * 6 in Sequenz usw.) Allzweck-Computing ist über OpenCL, CUDA usw. verfügbar, aber die Hardware ist immer noch kein voll funktionsfähiger "SIMD-Coprozessor" weil (a) Sie immer noch hardwarespezifische Register hämmern müssen, um zur GPU-Funktionalität zu gelangen; (b) das Lesen vom GPU-VRAM ist aufgrund des PCIe-Bus-Overheads sehr langsam (das Lesen von der GPU ist in Bezug auf die aktuelle Architektur nicht sehr optimiert); (c) die Speicher- und Cache-Architektur ist nicht kohärent mit der CPU; Es liegt immer noch viel ältere Hardware mit festen Funktionen herum.
  • Present (OpenGL 4.x): Viele der alten Hardware mit festen Funktionen wurden entfernt. Die GPU-Leselatenz wurde etwas verbessert. IOMMUs ermöglichen eine (übersetzte) hardwareunterstützte Zuordnung zwischen VRAM und Systemspeicher. Außerdem wurde eine Hardware-Tessellation eingeführt, die Elemente mit fester Funktion zurückbringt.
  • Zukunft ( HSA): Die GPU ist im Grunde ein Co-Prozessor. Es ist nahezu vollständig in die CPU integriert, mit sehr geringer Impedanz (für Lese- / Schreibvorgänge) zwischen GPU und CPU, selbst für dedizierte GPUs auf dem PCIe-Bus. Vollständig kohärente Speicherarchitektur - "mi memoria es su memoria" (mein Gedächtnis ist Ihr Gedächtnis). Userspace-Programme können aus "VRAM" genauso lesen wie aus dem Systemspeicher ohne Treiber-Shim, und die Hardware kümmert sich darum. Sie haben die CPU für die "serielle" Verarbeitung (tun Sie dies, dann tun Sie das, dann tun Sie das, dann tun Sie das) für bescheidene Datenmengen und die GPU für die "parallele" Verarbeitung (führen Sie diesen Vorgang für diesen riesigen Datensatz aus und teilen Sie ihn auf nach Belieben). Die Karte, auf der sich die GPU befindet, verfügt möglicherweise noch über ROPs, HDMI-Codec usw., aber dieses Zeug ist für die Displayausgabe erforderlich.
allquixotic
quelle
Ihr letzter Punkt ist großartig und gilt auch für mehr als nur OpenGL1.x / 2.x-Dinge. Aufgrund der unglaublichen Komplexität der Logik in GPUs ist es fast selbstverständlich, dass irgendwo Fehler auftreten. Normalerweise werden die meisten Fehler in der Logik behoben, bevor sie zu einem physischen Chip werden, aber es kann einige seltsame Eckfälle geben, die immer noch auftreten können. In diesem Fall müssen die Treiber die Funktion selbst implementieren, um den fehlerhaften Teil der Hardware zu umgehen. Solche Dinge sind häufig der Grund, warum Sie bei Treiberaktualisierungen möglicherweise Funktions- / Leistungsverbesserungen erhalten.
Ben Richards