What Irregularity Costs: CUDA C++, Rust, and Triton on a Hash-Blocked GPU Workload
Diese Arbeit zeigt auf, dass CUDA C++, Rust und Triton bei regulären GPU-Workloads zwar ähnlich performen, ihre Effizienz jedoch bei irregulären Hash-Block-Aufgaben aufgrund sprachspezifischer Einschränkungen bei der Ausdruck von atomaren Operationen und Schleifengrenzen drastisch divergiert, wobei Rust unter Problemen der Cache-Kohärenz leidet und Triton unter unmaskierbaren Atomics sowie Beschränkungen der Schleifenkontrolle zur Kompilierzeit.
Originalarbeit lizenziert unter CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/). Dies ist eine KI-generierte Erklärung des untenstehenden Papers. Sie wurde nicht von den Autoren verfasst oder gebilligt. Für technische Genauigkeit konsultieren Sie das Originalpaper. Vollständigen Haftungsausschluss lesen
Die Bühne und die Akteure
Stellen Sie sich vor, Sie versuchen, ein 3D-Modell eines Raumes mit einer Kamera zu erstellen, die tausende von Bildern aufnimmt. Um dies zu ermöglichen, muss Ihr Computer eine gewaltige Menge an Daten über jedes winzige Stück Raum in diesem Zimmer organisieren. Dies ist die Welt der GPU-Programmierung, in der „GPUs“ die superschnellen Grafikchips innerhalb von Computern sind, die auch brillant darin sind, Millionen von mathematischen Berechnungen gleichzeitig durchzuführen.
Normalerweise, wenn Menschen verschiedene Programmiersprachen für diese Chips vergleichen, testen sie diese an sehr ordentlichen, vorhersehbaren Aufgaben, wie etwa dem Multiplizieren riesiger Zahlenmatrizen. Es ist, als würde man ein Rennauto auf einer perfekt geraden, leeren Autobahn testen. Jede Spur ist gleich breit, und jeder Fahrer weiß genau, wie lange das Rennen dauern wird. Aber die reale Welt ist chaotisch. In Anwendungen wie virtueller Realität oder Roboter-Navigation muss der Computer mit chaotischen, unvorhersehbaren Daten umgehen. Es ist, als würde man dasselbe Rennauto in eine belebte, kurvenreiche Stadt schicken, in der zufällig Staus entstehen und Fahrer ständig anhalten und wieder anfahren müssen. Diese Arbeit stellt eine einfache, aber entscheidende Frage: Wenn die Straße chaotisch wird, verhalten sich dann alle Programmiersprachen gleich, oder bleiben einige im Verkehr stecken, während andere einfach hindurchrasen?
Das große GPU-Sprach-Duell
In dieser Studie nahmen Forscher drei gängige Wege, um mit diesen Superchips zu kommunizieren – CUDA C++ (der klassische, handgeschriebene Standard), Rust (eine moderne Sprache, die für Sicherheit bekannt ist) und Triton (ein neueres Werkzeug, das das Codieren erleichtern soll) – und ließen sie eine sehr spezifische, chaotische Aufgabe bewältigen: die Erstellung einer 3D-Karte eines Raumes mithilfe einer „Hashtabelle“.
Stellen Sie sich eine Hashtabelle wie eine riesige, chaotische Umkleidekabine vor. Sie haben tausende von Menschen (Datenpunkte), die versuchen, ein Schließfach (einen Platz im Speicher) zu finden, um ihre Sachen zu verstauen. Manchmal ist das Schließfach, das sie wollen, leer, also nehmen sie es. Aber oft ist das Schließfach bereits belegt, sodass sie das nächste prüfen müssen, und das nächste, bis sie einen freien Platz finden. In einer perfekten Welt findet jeder sofort ein Schließfach. In dieser „irregulären“ Arbeitslast findet manche Leute ihre Schließfächer sofort, während andere lange suchen müssen, und alle kämpfen gleichzeitig um dieselben wenigen Schließfächer.
Die Forscher ließen denselben exakten Job in allen drei Sprachen laufen und maßen, wie schnell sie fertig wurden. Die Ergebnisse waren ein Schock: Die Sprachen verhielten sich je nach Art der Arbeit völlig unterschiedlich.
Der „reguläre“ Teil: Ein Unentschieden
Zuerst testeten sie den „regulären“ Teil der Aufgabe, was so ist, als würde man einen Flur entlanggehen und jede Wand streichen, die man sieht. Dieser Teil ist vorhersehbar. Bei dieser Aufgabe waren alle drei Sprachen fast identisch. Egal, ob man das klassische CUDA, das moderne Rust oder das einfach zu bedienende Triton verwendete – sie waren in etwa gleich schnell fertig. Wenn man nur diese ordentlichen, vorhersehbaren Tests betrachtet (was die meisten anderen Studien tun), würde man denken, dass es keine Rolle spielt, welche Sprache man wählt.
Der „irreguläre“ Teil: Die große Spaltung
Dann testeten sie den „irregulären“ Teil: die chaotische Suche in der Umkleidekabine. Hier ändert sich die Geschichte dramatisch.
- Rust vs. CUDA C++: Die Sprache Rust performte fast genauso gut wie das handgeschriebene CUDA C++. Sie war nur ein winziges Stück langsamer (etwa 1 % bis 3 % in einigen Fällen), was praktisch ein Unentschieden ist. Rust bewies, dass es den unordentlichen, unvorhersehbaren Verkehr genauso gut bewältigen kann wie den Veteranen.
- Tritons Kampf: Triton hingegen stieß gegen eine massive Wand. Bei der chaotischen Suchaufgabe war es mehr als ata der 10-mal langsamer als die anderen beiden. In einigen realen Tests mit tatsächlichen Raumscans war es sogar fast 30-mal langsamer.
Warum blieb Triton stecken?
Die Forscher sagten nicht einfach nur „Triton ist langsam“; sie fanden heraus, warum es stecken blieb, und es lag nicht daran, dass der Code schlecht geschrieben war. Es lag daran, wie die Sprache aufgebaut ist.
Stellen Sie sich Triton als einen strengen Lehrer vor, der darauf besteht, dass jeder Schüler in einer Klasse für eine feste Zeit auf seinem Platz bleiben muss, selbst wenn er seine Arbeit früher erledigt hat. In der chaotischen Umkleidekabine finden manche Threads (Schüler) ein Schließfach in einer Sekunde, während andere zehn Sekunden brauchen.
- Das Problem: Triton zwingt die schnellen Threads dazu, in einer Schleife zu warten, bis der langsamste Thread fertig ist, obwohl sie selbst nichts mehr zu tun haben. Es ist wie ein Rennen, bei dem der Gewinner stillstehen muss und warten muss, bis der Letzte die Ziellinie überquert, bevor überhaupt jemand die Rennstrecke verlassen darf.
- Das „Masken“-Problem: Darüber hinaus fehlt Triton ein spezielles Werkzeug (eine sogenannte „Maske“), das es den schnellen Threads ermöglicht, die Arbeit komplett einzustellen. Stattdessen müssen sie eine Dummy-Aufgabe weiter ausführen, was Energie verschwendet und das System verstopft. Die Forscher fanden heraus, dass diese Designentscheidung den Computer dazu zwang, eine massive Menge an nutzloser Arbeit zu leisten, was alles um den Faktor 10 bis 30 verlangsamte.
- Eine verborgene Gefahr: Es gab auch ein Sicherheitsproblem. Da Triton ein festes Zeitlimit für die Suche erzwingt, könnte die Suche aufgeben und die Suche abbrechen, wenn die Umkleidekabine zu voll wird. Das bedeutet, der Computer wirft Teile des 3D-Raums lautlos weg und erstellt so unsichtbare Löcher im finalen Modell. Die Forscher fanden heraus, dass Triton bei bestimmten Crowd-Leveln ganze Oberflächenstücke verlor, während die anderen Sprachen diese perfekt fanden.
Warum Rust etwas langsamer war (Die unsichtbare Falle)
Rust war sehr nah am Sieg, aber es war nicht ganz so schnell wie der handgeschriebene CUDA-Code. Die Forscher verbrachten viel Zeit damit, herauszufinden, warum, indem sie die Anzahl der Instruktionen und den genutzten Speicher prüften. Sie fanden heraus, dass Rust tatsächlich weniger Arbeit verrichtete als CUDA, und dennoch langsamer war.
Der Übeltäter war eine versteckte Falle in der Art und Weise, wie Rust Sicherheit handhabt. Rust besitzt ein Feature, das das Lesen gemeinsam genutzter Daten „sicher“ macht, indem es sicherstellt, dass jeder die gleiche Version sieht. Doch auf diesen spezifischen Chips erzwingt die „sichere“ Art, Daten zu lesen, dass der Computer seinen schnellsten Speicher-Cache überspringt und stattdigt auf einen langsameren zugreift. Es ist wie ein Sicherheitsbeamter, der darauf besteht, jedes einzelne Paket am Eingang zu kontrollieren, obwohl die Pakete bereits als sicher bekannt sind. Dieser zusätzliche Schritt verlangsamte Rust um etwa 20–30 %, aber das war ein geringer Preis im Vergleich zum massiven Slowdown von Triton.
Das Fazit
Die wichtigste Lehre dieser Arbeit ist, dass man eine Programmiersprache nicht allein anhand ihrer Leistung bei ordentlichen, vorhersehbaren Aufgaben beurteilen kann.
Wenn man nur auf der „regulären“ Autobahn testet, sehen Rust, CUDA und Triton alle wie Champions aus. Aber sobald man sie in den „irregulären“ Stadtverkehr der realen 3D-Kartierung wirft, klaffen die Ergebnisse weit auseinander.
- Rust ist ein starker Kontender, der fast so schnell bleibt wie der beste handgeschriebene Code.
- Triton zwar großartig für ordentliche Aufgaben, kämpft jedoch heftig mit chaotischen, unvorhersehbaren Arbeiten und wird um das Zehn- oder Dutzendfache langsamer und verursacht potenziell Datenverlust, ohne dass es jemand bemerkt.
Die Forscher kommen zu dem Schluss, dass es bei Aufgaben, die mit unordentlichen Realdaten zu tun haben, nicht nur eine kleine Unannehmlichkeit ist, die falsche Sprache zu wählen; es kann dazu führen, dass Ihr Programm unbrauchbar langsam wird oder lautlos versagt. Sie stellten auch fest, dass viele bisherige Studien dies übersehen haben, da sie nur die „regulären“ Teile testeten und die gefährlichen, chaotischen Teile ununtersucht ließen.
Ertrinken Sie in Arbeiten in Ihrem Fachgebiet?
Erhalten Sie tägliche Digests der neuesten Arbeiten passend zu Ihren Forschungsbegriffen — mit technischen Zusammenfassungen, in Ihrer Sprache.