WebGPU: Moderne GPU-Zugriffe im Browser

Hier erfährst du, wie WebGPU das Leistungspotenzial der GPU freisetzt, um die Leistung beim maschinellen Lernen zu beschleunigen und das Grafikrendering zu verbessern.

Corentin Wallez
Corentin Wallez
François Beaufort
François Beaufort

Die neue WebGPU API ermöglicht enorme Leistungssteigerungen bei Grafik- und ML-Arbeitslasten. In diesem Artikel wird untersucht, wie WebGPU eine Verbesserung gegenüber der aktuellen Lösung von WebGL ist, und bietet einen kleinen Vorgeschmack auf zukünftige Entwicklungen. Aber zuerst wollen wir uns erklären, warum WebGPU entwickelt wurde.

Kontext auf WebGPU

2011 wurde WebGL in Chrome eingeführt. Da Webanwendungen die Vorteile von GPUs nutzen können, ermöglicht WebGL fantastische Erlebnisse im Web – von Google Earth über interaktive Musikvideos bis hin zu 3D-Rundgängen für Immobilien und mehr. WebGL basierte auf der OpenGL-Familie von APIs, die erstmals 1992 entwickelt wurden. Das ist schon lange her! Seitdem hat sich die GPU-Hardware erheblich weiterentwickelt.

Um mit dieser Entwicklung Schritt zu halten, wurde eine neue Art von APIs entwickelt, die eine effizientere Interaktion mit moderner GPU-Hardware ermöglichen. APIs wie Direct3D 12, Metal und Vulkan Diese neuen APIs haben neue und anspruchsvolle Anwendungsfälle für die GPU-Programmierung unterstützt, z. B. den explosionsartigen Anstieg des maschinellen Lernens und Fortschritte bei den Rendering-Algorithmen. WebGPU ist der Nachfolger von WebGL und bringt die Fortschritte dieser neuen Klasse moderner APIs ins Web.

WebGPU eröffnet viele neue GPU-Programmiermöglichkeiten im Browser. Sie spiegelt besser wider, wie moderne GPU-Hardware funktioniert, und legt gleichzeitig die Grundlage für erweiterte GPU-Funktionen. Die API ist seit 2017 Teil der W3C-Gruppe „GPU für das Web“ und ist ein Gemeinschaftsprojekt vieler Unternehmen wie Apple, Google, Mozilla, Microsoft und Intel. Und nach 6 Jahren Arbeit freuen wir uns, verkünden zu können, dass eine der größten Ergänzungen der Webplattform endlich verfügbar ist!

WebGPU ist derzeit in Chrome 113 für ChromeOS, macOS und Windows verfügbar. Weitere Plattformen folgen demnächst. Ein großes Dankeschön geht insbesondere an andere Chromium-Beitragende und Intel, die dazu beigetragen haben.

Werfen wir nun einen Blick auf einige der aufregenden Anwendungsfälle, die WebGPU ermöglicht.

Neue GPU-Arbeitslasten für das Rendering nutzen

WebGPU-Funktionen wie Compute-Shader ermöglichen die Portierung neuer Algorithmenklassen auf die GPU. Beispielsweise können Algorithmen dynamische Details zu Szenen hinzufügen, physikalische Phänomene simulieren und vieles mehr. Es gibt sogar Arbeitslasten, die bisher nur in JavaScript ausgeführt werden konnten, und die nun auf die GPU verschoben werden können.

Das folgende Video zeigt, wie der Algorithmus der Marschwürfel zur Triangulierung der Oberfläche dieser Metabälle verwendet wird. In den ersten 20 Sekunden des Videos hat der Algorithmus, wenn er in JavaScript ausgeführt wird, Schwierigkeiten, mit der Seite Schritt zu halten, die nur bei 8 fps ausgeführt wird, was zu ruckeligen Animationen führt. Um in JavaScript leistungsstark zu bleiben, müssten wir die Detailebene deutlich reduzieren.

Es ist ein Unterschied zwischen Tag und Nacht, wenn wir denselben Algorithmus in einen Compute-Shader verschieben, der nach 20 Sekunden im Video zu sehen ist. Die Leistung verbessert sich drastisch, da die Seite jetzt mit reibungslosen 60 fps ausgeführt wird. Es gibt noch viel Spielraum für andere Effekte. Außerdem wird die Haupt-JavaScript-Schleife der Seite vollständig für andere Aufgaben freigegeben, sodass Interaktionen mit der Seite responsiv bleiben.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"></ph> <ph type="x-smartling-placeholder">
</ph> Metaball-Demo

WebGPU ermöglicht auch komplexe visuelle Effekte, die zuvor nicht praktikabel waren. Im folgenden Beispiel, das in der beliebten Bibliothek Babylon.js erstellt wurde, wird die Meeresoberfläche vollständig auf der GPU simuliert. Die realistische Dynamik ergibt sich aus vielen unabhängigen Wellen, die einander addiert werden. Es wäre jedoch zu teuer, jede Welle direkt zu simulieren.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"></ph> <ph type="x-smartling-placeholder">
</ph> Die Ozean-Demo

Aus diesem Grund wird in der Demo der erweiterte Algorithmus Fast Fourier Transform verwendet. Anstatt alle Wellen als komplexe Positionsdaten darzustellen, werden hier die spektralen Daten verwendet, sodass Berechnungen viel effizienter durchgeführt werden können. Dann verwendet jeder Frame die Fourier-Transformation, um spektrale Daten in Positionsdaten umzuwandeln, die die Höhe der Wellen darstellen.

Schnellere ML-Inferenz

WebGPU ist außerdem nützlich, um das maschinelle Lernen zu beschleunigen, das in den letzten Jahren zu einer wichtigen Nutzung von GPUs geworden ist.

Schon seit Langem verwenden Creative-Entwickler die Rendering-API von WebGL für andere Vorgänge wie Berechnungen für maschinelles Lernen. Dazu müssen jedoch die Pixel von Dreiecken gezeichnet werden, um die Berechnungen zu starten. Außerdem müssen Tensordaten sorgfältig in die Textur gepackt und entpackt werden, anstatt allgemeine Speicherzugriffe zu verwenden.

<ph type="x-smartling-placeholder">
</ph> Darstellung der Ineffizienzen bei der Ausführung eines einzelnen ML-Operators mit WebGL, einschließlich redundanter Speicherlasten, redundanter Berechnungen und geringer Werte, die pro Thread geschrieben werden. <ph type="x-smartling-placeholder">
</ph> Ausführung mit einem einzelnen ML-Operator mit WebGL

Wenn WebGL auf diese Weise verwendet wird, müssen Entwickler ihren Code umständlich an die Erwartungen an eine API anpassen, die nur zum Zeichnen vorgesehen ist. In Kombination mit dem Fehlen grundlegender Funktionen wie der gemeinsame Speicherzugriff zwischen den Berechnungen führt dies zu doppelten Arbeitsaufwand und zu geringer Leistung.

Compute-Shader sind die wichtigste neue Funktion von WebGPU und beseitigen diese Probleme. Compute-Shader bieten ein flexibleres Programmiermodell, das sich die massive parallele Natur der GPU zunutze macht und nicht durch die strenge Struktur von Renderingvorgängen eingeschränkt ist.

<ph type="x-smartling-placeholder">
</ph> Die verschiedenen Effizienzzuwächse bei WebGPU-Rechen-Shadern, einschließlich gemeinsamer Speicherlasten, gemeinsamer Berechnungen und flexibler Schreibvorgänge in den Arbeitsspeicher. <ph type="x-smartling-placeholder">
</ph> WebGPU-Computing-Shader-Effizienz

Compute-Shader bieten mehr Möglichkeiten für die gemeinsame Nutzung von Daten und Berechnungsergebnissen innerhalb von Gruppen von Shader-Arbeiten, um die Effizienz zu verbessern. Dies kann gegenüber früheren Versuchen, WebGL für denselben Zweck zu verwenden, erhebliche Vorteile bieten.

Ein Beispiel für die Effizienzsteigerungen, die dies mit sich bringen kann: Ein Anfangsport eines Bild-Diffusion-Modells in TensorFlow.js zeigt bei der Umstellung von WebGL auf WebGPU auf einer Vielzahl von Hardware eine 3-fache Leistungssteigerung auf. Auf einigen Hardware-Tests wurde das Bild in weniger als 10 Sekunden gerendert. Da es sich hierbei um einen frühen Port handelt, sind wir überzeugt, dass sowohl bei WebGPU als auch bei TensorFlow.js noch mehr Verbesserungen möglich sind. Sehen Sie sich Neues bei Web ML im Jahr 2023 an. Google I/O-Session

Bei WebGPU geht es aber nicht nur darum, GPU-Funktionen ins Web zu bringen.

Zuerst für JavaScript entwickelt

Die Funktionen, mit denen diese Anwendungsfälle möglich sind, stehen plattformspezifischen Desktop- und Mobilentwicklern schon eine Weile zur Verfügung. Es war unsere Herausforderung, sie so zu präsentieren, dass sie sich als natürlicher Teil der Webplattform anfühlen.

WebGPU wurde im Nachhinein von mehr als einem Jahrzehnt von Entwicklern entwickelt, die hervorragende Arbeit mit WebGL leisten. Wir konnten die aufgetretenen Probleme, die aufgetretenen Engpässe und die aufgetretenen Probleme berücksichtigen und das gesamte Feedback in diese neue API einfließen lassen.

Wir haben festgestellt, dass das globale Zustandsmodell von WebGL die Erstellung robuster, zusammensetzbarer Bibliotheken und Anwendungen schwierig und anfällig macht. WebGPU reduziert also deutlich den Zustand, den Entwickler beim Senden der GPU-Befehle im Auge behalten müssen.

Wir haben gehört, dass das Debugging von WebGL-Anwendungen schwierig war. Daher umfasst WebGPU flexiblere Fehlerbehandlungsmechanismen, die die Leistung nicht beeinträchtigen. Außerdem haben wir alles daran gesetzt, dass jede Nachricht, die Sie von der API erhalten, leicht verständlich und umsetzbar ist.

Außerdem stellten wir fest, dass der Aufwand für zu viele JavaScript-Aufrufe bei komplexen WebGL-Anwendungen häufig einen Engpass darstellt. Daher ist die WebGPU API weniger Chatten, sodass Sie mit weniger Funktionsaufrufen mehr erreichen können. Wir konzentrieren uns auf eine umfangreiche Validierung im Vorfeld, um die kritische Zeichenschleife so schlank wie möglich zu halten. Außerdem bieten wir neue APIs wie Render Bundles an, mit denen Sie eine große Anzahl von Zeichenbefehlen im Voraus aufzeichnen und in einem einzigen Aufruf wiedergeben können.

Hier ist eine weitere Demo von Babylon.js, um zu zeigen, welchen entscheidenden Unterschied eine Funktion wie Rendering-Bundles bewirken kann. Der WebGL 2-Renderer kann alle JavaScript-Aufrufe ausführen, um diese Kunstgalerie etwa 500 Mal pro Sekunde zu rendern. Das ist ziemlich gut!

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"></ph> <ph type="x-smartling-placeholder">
</ph> Die Kunstgalerie

Ihr WebGPU-Renderer ermöglicht jedoch eine Funktion, die sie Snapshot-Rendering nennen. Diese Funktion basiert auf Rendering-Bundles für WebGPUs und ermöglicht so eine 10-mal schnellere Einreichung derselben Szene. Durch den deutlich reduzierten Aufwand kann WebGPU komplexere Szenen rendern, während Anwendungen gleichzeitig mehr mit JavaScript tun können.

Moderne Grafik-APIs sind für ihre Komplexität bekannt und nutzen Einfachheit gegenüber extremen Optimierungsmöglichkeiten. WebGPU hingegen konzentriert sich auf die plattformübergreifende Kompatibilität und handhabt traditionell schwierige Themen wie die Ressourcensynchronisierung in den meisten Fällen automatisch.

Dies hat den glücklichen Nebeneffekt, dass WebGPU einfach zu erlernen und zu verwenden ist. Sie basiert auf vorhandenen Funktionen der Webplattform für das Laden von Bildern und Videos und nutzt bekannte JavaScript-Muster wie Promise-Objekte für asynchrone Vorgänge. Dies trägt dazu bei, die erforderliche Menge an Boilerplate-Code auf ein Minimum zu reduzieren. Für das erste Dreieck benötigen Sie weniger als 50 Zeilen Code.

<canvas id="canvas" width="512" height="512"></canvas>
<script type="module">
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  const context = canvas.getContext("webgpu");
  const format = navigator.gpu.getPreferredCanvasFormat();
  context.configure({ device, format });

  const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
  const shaderModule = device.createShaderModule({ code });
  const pipeline = device.createRenderPipeline({
    layout: "auto",
    vertex: {
      module: shaderModule,
      entryPoint: "vertexMain",
    },
    fragment: {
      module: shaderModule,
      entryPoint: "fragmentMain",
      targets: [{ format }],
    },
  });
  const commandEncoder = device.createCommandEncoder();
  const colorAttachments = [
    {
      view: context.getCurrentTexture().createView(),
      loadOp: "clear",
      storeOp: "store",
    },
  ];
  const passEncoder = commandEncoder.beginRenderPass({ colorAttachments });
  passEncoder.setPipeline(pipeline);
  passEncoder.draw(3);
  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);
</script>

Fazit

Es ist aufregend, all die neuen Möglichkeiten zu sehen, die WebGPU auf die Webplattform bietet, und wir sind schon gespannt auf die coolen neuen Anwendungsfälle für WebGPU!

Um WebGL wurde ein dynamisches Ökosystem aus Bibliotheken und Frameworks aufgebaut, das auch WebGPU unterstützt. Die Unterstützung für WebGPU ist in Arbeit oder wird in vielen gängigen JavaScript-WebGL-Bibliotheken bereits abgeschlossen. In einigen Fällen ist die Nutzung der Vorteile von WebGPU möglicherweise so einfach wie das Ändern eines einzelnen Flags.

<ph type="x-smartling-placeholder">
</ph> Babylon.js, Konstrukt 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js und Unity.
Frameworks, Anwendungen und Bibliotheken mit fertigen oder laufenden WebGPU-Ports

Diese erste Version in Chrome 113 ist nur der Anfang. Unsere erste Version ist zwar für Windows, ChromeOS und MacOS, aber wir planen, WebGPU in naher Zukunft auch für die übrigen Plattformen wie Android und Linux einzuführen.

Und nicht nur das Chrome-Team hat an der Einführung von WebGPU gearbeitet. Implementierungen für Firefox und WebKit sind ebenfalls in Arbeit.

Darüber hinaus werden beim W3C bereits neue Funktionen entwickelt, die verfügbar gemacht werden können, wenn sie in der Hardware verfügbar sind. Beispiel: Wir planen, in Chrome bald die Unterstützung von 16-Bit-Gleitkommazahlen in Shadern und die Anleitungsklasse DP4a zu ermöglichen, um die Leistung des maschinellen Lernens weiter zu verbessern.

WebGPU ist eine umfangreiche API, die eine erstaunliche Leistung ermöglicht, wenn Sie in sie investieren. Heute können wir die Vorteile nur allgemein beschreiben. Wenn Sie jedoch mit WebGPU loslegen möchten, sehen Sie sich unser einführendes Codelab Ihre erste WebGPU-App an. In diesem Codelab entwickeln Sie eine GPU-Version von Conway's Game of Life. In diesem Codelab werden Sie Schritt für Schritt durch den Prozess geführt, sodass Sie ihn auch dann ausprobieren können, wenn Sie zum ersten Mal mit der GPU-Entwicklung arbeiten.

Die WebGPU-Beispiele sind ebenfalls ein guter Ort, um sich mit der API vertraut zu machen. Sie reichen vom traditionellen „Hallo“-Dreieck zu umfassenderen Rendering- und Computing-Pipelines führt und eine Vielzahl von Techniken demonstriert. Außerdem können Sie sich auch unsere anderen Ressourcen ansehen.