WebGPU: Ontgrendeling van moderne GPU-toegang in de browser

Ontdek hoe WebGPU de kracht van de GPU ontgrendelt voor snellere machine learning-prestaties en betere grafische weergave.

De nieuwe WebGPU API ontgrendelt enorme prestatieverbeteringen in grafische en machine learning-workloads. Dit artikel onderzoekt hoe WebGPU een verbetering is ten opzichte van de huidige oplossing van WebGL, met een voorproefje van toekomstige ontwikkelingen. Maar laten we eerst wat context bieden waarom WebGPU is ontwikkeld.

Context op WebGPU

WebGL verscheen in 2011 in Chrome . Door webapplicaties te laten profiteren van GPU's, maakt WebGL geweldige ervaringen op internet mogelijk: van Google Earth tot interactieve muziekvideo's, tot 3D-rondleidingen over onroerend goed en meer. WebGL was gebaseerd op de OpenGL- familie van API's die voor het eerst werd ontwikkeld in 1992. Dat is lang geleden! En je kunt je voorstellen dat de GPU-hardware sinds die tijd aanzienlijk is geëvolueerd.

Om deze evolutie bij te houden, werd een nieuw soort API's ontwikkeld om efficiënter te kunnen communiceren met moderne GPU-hardware. API's zoals Direct3D 12 , Metal en Vulkan . Deze nieuwe API's hebben nieuwe en veeleisende gebruiksscenario's voor GPU-programmering ondersteund, zoals de explosie van machine learning en de vooruitgang in renderingalgoritmen. WebGPU is de opvolger van WebGL en brengt de vooruitgang van deze nieuwe klasse moderne API's naar het web.

WebGPU ontgrendelt veel nieuwe GPU-programmeermogelijkheden in de browser. Het weerspiegelt beter hoe moderne GPU-hardware werkt, terwijl het ook een basis legt voor meer geavanceerde GPU-mogelijkheden in de toekomst. De API is sinds 2017 onderdeel van de 'GPU for the Web'-groep van het W3C en is een samenwerking tussen veel bedrijven zoals Apple, Google, Mozilla, Microsoft en Intel. En nu, na zes jaar werk, zijn we verheugd om aan te kondigen dat een van de grootste toevoegingen aan het webplatform eindelijk beschikbaar is!

WebGPU is vandaag beschikbaar in Chrome 113 op ChromeOS, macOS en Windows, en binnenkort volgen ook andere platforms. Hartelijk dank aan andere Chromium-bijdragers en Intel in het bijzonder die dit mogelijk hebben gemaakt.

Laten we nu eens kijken naar enkele van de opwindende gebruiksscenario's die WebGPU mogelijk maakt.

Ontgrendel nieuwe GPU-workloads voor rendering

WebGPU-functies zoals compute shaders zorgen ervoor dat nieuwe klassen algoritmen naar de GPU kunnen worden geport. Bijvoorbeeld algoritmen die meer dynamische details aan scènes kunnen toevoegen, fysieke fenomenen kunnen simuleren en meer! Er zijn zelfs workloads die voorheen alleen in JavaScript konden worden uitgevoerd, maar die nu naar de GPU kunnen worden verplaatst.

De volgende video toont het marcherende kubusalgoritme dat wordt gebruikt om het oppervlak van deze metaballen te trianguleren. In de eerste 20 seconden van de video heeft het algoritme, wanneer het in JavaScript draait, moeite om de pagina bij te houden die slechts op 8 FPS draait, wat resulteert in janky-animatie. Om het in JavaScript goed te laten presteren, zouden we het detailniveau veel moeten verlagen.

Het is een verschil van dag en nacht als we hetzelfde algoritme naar een compute shader verplaatsen, die na 20 seconden in de video te zien is. De prestaties verbeteren dramatisch nu de pagina draait op een soepele 60 FPS en er is nog steeds veel prestatieruimte voor andere effecten. Bovendien wordt de belangrijkste JavaScript-lus van de pagina volledig vrijgemaakt voor andere taken, waardoor interacties met de pagina responsief blijven.

De metaballs-demo

WebGPU maakt ook complexe visuele effecten mogelijk die voorheen niet praktisch waren. In het volgende voorbeeld, gemaakt in de populaire Babylon.js- bibliotheek, wordt het oceaanoppervlak volledig op de GPU gesimuleerd. De realistische dynamiek ontstaat doordat vele onafhankelijke golven bij elkaar worden opgeteld. Maar het rechtstreeks simuleren van elke golf zou te duur zijn.

De oceaandemo

Daarom gebruikt de demo een geavanceerd algoritme genaamd Fast Fourier Transform . In plaats van alle golven als complexe positionele gegevens weer te geven, worden hierbij de spectrale gegevens gebruikt, wat veel efficiënter is om berekeningen uit te voeren. Vervolgens gebruikt elk frame de Fourier-transformatie om spectrale gegevens om te zetten in positionele gegevens die de hoogte van de golven vertegenwoordigen.

Snellere ML-inferentie

WebGPU is ook nuttig om machine learning te versnellen, wat de afgelopen jaren een belangrijk gebruik van GPU's is geworden.

Lange tijd hebben creatieve ontwikkelaars de rendering-API van WebGL opnieuw ingericht om niet-renderingbewerkingen uit te voeren, zoals machine learning-berekeningen. Dit vereist echter het tekenen van de pixels van driehoeken als een manier om de berekeningen te starten, en het zorgvuldig inpakken en uitpakken van tensorgegevens in textuur in plaats van geheugentoegang voor meer algemene doeleinden.

Een illustratie van de inefficiënties bij de uitvoering van een enkele ML-operator met WebGL, inclusief redundante geheugenbelasting, redundante berekeningen en weinig waarden die per thread worden geschreven.
Eén enkele ML-operatoruitvoering met WebGL.

Door WebGL op deze manier te gebruiken, moeten ontwikkelaars hun code op onhandige wijze aanpassen aan de verwachtingen van een API die alleen is ontworpen voor tekenen. Gecombineerd met het ontbreken van basisfuncties zoals gedeelde geheugentoegang tussen berekeningen, leidt dit tot dubbel werk en suboptimale prestaties.

Compute shaders zijn de belangrijkste nieuwe functie van WebGPU en nemen deze pijnpunten weg. Compute shaders bieden een flexibeler programmeermodel dat profiteert van het enorm parallelle karakter van de GPU, zonder te worden beperkt door de strikte structuur van renderingbewerkingen.

De verschillende efficiëntiewinsten in WebGPU-compute-shaders, waaronder gedeelde geheugenbelasting, gedeelde berekeningen en flexibel schrijven naar geheugen.
Efficiëntie van WebGPU-computershaders.

Compute shaders bieden meer mogelijkheden voor het delen van gegevens en berekeningsresultaten binnen groepen shader-werkzaamheden voor een betere efficiëntie. Dit kan tot aanzienlijke winsten leiden ten opzichte van eerdere pogingen om WebGL voor hetzelfde doel te gebruiken.

Als voorbeeld van de efficiëntiewinst die dit met zich mee kan brengen: een initiële port van een beelddiffusiemodel in TensorFlow.js toont een prestatiewinst van drie keer op een verscheidenheid aan hardware wanneer deze van WebGL naar WebGPU wordt verplaatst. Op sommige van de geteste hardware werd het beeld binnen 10 seconden weergegeven. En omdat dit een vroege port was, denken we dat er nog meer verbeteringen mogelijk zijn in zowel WebGPU als TensorFlow.js! Bekijk Wat is er nieuw met Web ML in 2023? Google I/O-sessie.

Maar WebGPU gaat niet alleen over het beschikbaar maken van GPU-functies op internet.

Eerst ontworpen voor JavaScript

De functies die deze gebruiksscenario's mogelijk maken, zijn al een tijdje beschikbaar voor platformspecifieke desktop- en mobiele ontwikkelaars, en het is onze uitdaging geweest om ze bloot te leggen op een manier die aanvoelt als een natuurlijk onderdeel van het webplatform.

WebGPU is ontwikkeld met het voordeel achteraf van meer dan tien jaar ontwikkelaars die geweldig werk hebben verricht met WebGL. We konden de problemen die ze tegenkwamen, de knelpunten die ze tegenkwamen en de problemen die ze naar voren brachten, meenemen en al die feedback naar deze nieuwe API leiden.

We zagen dat het mondiale staatsmodel van WebGL het creëren van robuuste, samenstelbare bibliotheken en applicaties moeilijk en kwetsbaar maakte. WebGPU vermindert dus dramatisch de hoeveelheid status die ontwikkelaars moeten bijhouden tijdens het verzenden van de GPU-opdrachten.

We hebben gehoord dat het debuggen van WebGL-applicaties lastig was, dus bevat WebGPU flexibelere mechanismen voor foutafhandeling die de prestaties niet negatief beïnvloeden. En we hebben ons uiterste best gedaan om ervoor te zorgen dat elk bericht dat u terugkrijgt via de API gemakkelijk te begrijpen en uitvoerbaar is.

We zagen ook dat de overhead van het maken van te veel JavaScript-oproepen vaak een knelpunt vormde voor complexe WebGL-applicaties. Als gevolg hiervan is de WebGPU API minder spraakzaam, zodat u meer kunt bereiken met minder functieaanroepen. We concentreren ons op het vooraf uitvoeren van zware validatie, waarbij we de kritieke treklus zo slank mogelijk houden. En we bieden nieuwe API's zoals Render Bundles , waarmee u grote aantallen tekenopdrachten vooraf kunt opnemen en deze met één enkele oproep opnieuw kunt afspelen.

Om te laten zien wat een dramatisch verschil een functie als renderbundels kan maken, is hier nog een demo van Babylon.js. Hun WebGL 2-renderer kan alle JavaScript-aanroepen uitvoeren om deze kunstgaleriescène ongeveer 500 keer per seconde weer te geven. Dat is best goed!

De kunstgalerie

Hun WebGPU-renderer maakt echter een functie mogelijk die zij Snapshot Rendering noemen. Deze functie is gebouwd bovenop WebGPU's renderbundels en zorgt ervoor dat dezelfde scène meer dan 10x sneller kan worden ingediend. Dankzij deze aanzienlijk verminderde overhead kan WebGPU complexere scènes weergeven, terwijl applicaties parallel meer met JavaScript kunnen doen.

Moderne grafische API's staan ​​bekend om hun complexiteit en verruilen eenvoud voor extreme optimalisatiemogelijkheden. WebGPU daarentegen is gericht op platformonafhankelijke compatibiliteit, waarbij traditioneel moeilijke onderwerpen zoals de synchronisatie van bronnen in de meeste gevallen automatisch worden afgehandeld.

Dit heeft het prettige neveneffect dat WebGPU gemakkelijk te leren en te gebruiken is. Het vertrouwt op bestaande functies van het webplatform voor zaken als het laden van afbeeldingen en video's, en leunt op bekende JavaScript-patronen zoals Promises voor asynchrone bewerkingen. Hierdoor wordt de benodigde hoeveelheid boilerplate-code tot een minimum beperkt. U kunt uw eerste driehoek op het scherm krijgen in minder dan 50 regels 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>

Conclusie

Het is opwindend om alle nieuwe mogelijkheden te zien die WebGPU naar het webplatform brengt en we kijken uit naar alle coole nieuwe gebruiksscenario's die u voor WebGPU zult vinden!

Er is een levendig ecosysteem van bibliotheken en raamwerken rond WebGL gebouwd, en datzelfde ecosysteem wil graag WebGPU omarmen. Ondersteuning voor WebGPU is in uitvoering of al voltooid in veel populaire Javascript WebGL-bibliotheken, en in sommige gevallen kan het profiteren van de voordelen van WebGPU net zo eenvoudig zijn als het wijzigen van een enkele vlag!

Babylon.js, Construct 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js en Unity.
Frameworks, applicaties en bibliotheken met voltooide of lopende WebGPU-poorten.

En deze eerste release in Chrome 113 is nog maar een begin. Hoewel onze eerste release voor Windows, ChromeOS en MacOS is, zijn we van plan om WebGPU in de nabije toekomst naar de resterende platforms zoals Android en Linux te brengen.

En het is niet alleen het Chrome-team dat heeft gewerkt aan de lancering van WebGPU. Er zijn ook implementaties gaande in Firefox en WebKit.

Bovendien worden er op het W3C al nieuwe functies ontworpen die zichtbaar kunnen worden gemaakt als ze beschikbaar zijn in de hardware. Bijvoorbeeld: in Chrome zijn we van plan binnenkort ondersteuning in te schakelen voor 16-bits drijvende-kommagetallen in shaders en de DP4a-klasse van instructies voor nog meer prestatieverbeteringen op het gebied van machine learning.

WebGPU is een uitgebreide API die geweldige prestaties ontgrendelt als je erin investeert. Tegenwoordig konden we de voordelen ervan alleen op een hoog niveau bespreken, maar als je aan de slag wilt met WebGPU, bekijk dan ons inleidende Codelab, Je eerste WebGPU-app . In dit codelab bouw je een GPU-versie van de klassieke Conway's Game of Life. Dit codelab leidt u stap voor stap door het proces, zodat u het kunt uitproberen, zelfs als het de eerste keer is dat u GPU-ontwikkeling doet.

De WebGPU-voorbeelden zijn ook een goede plek om een ​​idee te krijgen van de API. Ze variëren van de traditionele "hallo-driehoek" tot completere rendering- en rekenpijplijnen, waarbij een verscheidenheid aan technieken worden gedemonstreerd. Bekijk ten slotte onze andere bronnen .