WebGPU: sblocco dell'accesso alle GPU moderne nel browser

Scopri come WebGPU sfrutta la potenza della GPU per velocizzare le prestazioni di machine learning e migliorare il rendering della grafica.

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

La nuova API WebGPU consente di ottenere enormi miglioramenti nelle prestazioni nei carichi di lavoro di grafica e machine learning. Questo articolo illustra come WebGPU sia un miglioramento rispetto all'attuale soluzione di WebGL, che offre un'anteprima dei futuri sviluppi. Prima, però, spieghiamo il motivo dello sviluppo di WebGPU.

Contesto su WebGPU

WebGL è approdato in Chrome nel 2011. Consentendo alle applicazioni web di sfruttare le GPU, WebGL permette di avere esperienze incredibili sul web, da Google Earth ai video musicali interattivi, alle procedure dettagliate per il settore immobiliare 3D e altro ancora. WebGL è basato sulla famiglia di API OpenGL, sviluppata per la prima volta nel 1992. È tanto tempo fa! E puoi immaginare che l'hardware GPU si sia evoluto in modo significativo da quel momento.

Per stare al passo con questa evoluzione, è stata sviluppata una nuova generazione di API per interagire in modo più efficiente con il moderno hardware GPU. API come Direct3D 12, Metal e Vulkan. Queste nuove API hanno supportato casi d'uso nuovi ed esigenti per la programmazione delle GPU, come l'esplosione del machine learning e i progressi negli algoritmi di rendering. WebGPU è il successore di WebGL, che introduce i progressi di questa nuova classe di API moderne sul web.

WebGPU sblocca molte nuove possibilità di programmazione GPU nel browser. Riflette meglio il funzionamento del moderno hardware GPU e getta anche le basi per funzionalità GPU più avanzate in futuro. L'API fa parte del gruppo GPU per il web di W3C dal 2017 ed è nata dalla collaborazione tra molte aziende quali Apple, Google, Mozilla, Microsoft e Intel. E ora, dopo 6 anni di lavoro, siamo lieti di annunciare che una delle più importanti aggiunte alla piattaforma web è finalmente disponibile!

WebGPU è già disponibile in Chrome 113 su ChromeOS, macOS e Windows, ma a breve anche su altre piattaforme. Grazie mille agli altri collaboratori di Chromium e a Intel in particolare che hanno contribuito a realizzare questo obiettivo.

Ora diamo un'occhiata ad alcuni degli entusiasmanti casi d'uso di WebGPU.

Sblocca nuovi carichi di lavoro GPU per il rendering

Le funzionalità di WebGPU, come gli shadowing di calcolo, consentono di trasferire nella GPU nuove classi di algoritmi. Ad esempio, sono in grado di aggiungere dettagli dinamici alle scene, simulare fenomeni fisici e altro ancora. Esistono anche carichi di lavoro che in precedenza potevano essere eseguiti solo in JavaScript, ma che ora possono essere spostati nella GPU.

Il seguente video mostra l'algoritmo dei cubi in marcia che viene utilizzato per triangolare la superficie di queste metaball. Nei primi 20 secondi del video, l'algoritmo, quando è in esecuzione in JavaScript, fatica a stare al passo con la velocità di esecuzione della pagina a soli 8 f/s, generando un'animazione scadente. Per mantenerlo ad alte prestazioni in JavaScript, dobbiamo abbassare molto il livello di dettagli.

La differenza tra il giorno e la notte avviene quando spostiamo lo stesso algoritmo su uno shardr elaborato, che viene visualizzato nel video dopo 20 secondi. Le prestazioni migliorano drasticamente, ora la pagina funziona a 60 f/s senza interruzioni e c'è ancora molto margine per altri effetti in termini di prestazioni. Inoltre, il loop JavaScript principale della pagina viene liberato completamente per altre attività, garantendo che le interazioni con la pagina rimangano reattive.

La demo sulle metaball

WebGPU consente inoltre effetti visivi complessi prima non erano pratici. Nell'esempio seguente, creato nella popolare libreria Babylon.js, la superficie dell'oceano viene simulata interamente sulla GPU. Le dinamiche realistiche sono create dalla somma di molte onde indipendenti. Ma simulare direttamente ogni onda sarebbe troppo costoso.

Demo di The Ocean

Ecco perché la demo utilizza un algoritmo avanzato chiamato Fast Fourier Transform. Anziché rappresentare tutte le onde come dati di posizione complessi, vengono utilizzati i dati spettrali che consentono di eseguire i calcoli in modo molto più efficiente. Successivamente, ogni frame utilizza la trasformata di Fourier per convertire i dati spettrali in quelli della posizione che rappresentano l'altezza delle onde.

Inferenza ML più rapida

WebGPU è utile anche per accelerare il machine learning, che negli ultimi anni è diventato un uso importante delle GPU.

Per molto tempo, gli sviluppatori di creatività riproponevano l'API di rendering di WebGL per eseguire operazioni non di rendering come i calcoli di machine learning. Tuttavia, ciò richiede di disegnare i pixel di triangoli per avviare i calcoli e di pacchettizzare e decomprimere accuratamente i dati di tensore nella texture invece di accedere alla memoria per uso più generico.

Illustrazione delle inefficienze nell'esecuzione di un singolo operatore ML con WebGL, inclusi carichi di memoria ridondanti, calcoli ridondanti e pochi valori scritti per thread.
Esecuzione di un singolo operatore ML con WebGL.

L'utilizzo di WebGL in questo modo richiede agli sviluppatori di conformare goffamente il proprio codice alle aspettative di un'API progettata solo per il disegno. Insieme alla mancanza di funzionalità di base come l'accesso alla memoria condivisa tra i calcoli, questo porta a un lavoro duplicato e a prestazioni non ottimali.

Gli mesh di computing sono la nuova funzionalità principale di WebGPU e li eliminano. Gli mesh di computing offrono un modello di programmazione più flessibile che sfrutta la natura a elevata parallelismo della GPU, pur non essendo vincolato dalla rigida struttura delle operazioni di rendering.

I vari miglioramenti di efficienza degli Shampoker di calcolo WebGPU, tra cui caricamenti di memoria condivisa, calcoli condivisi e scritture flessibili sulla memoria.
Efficienza del serverless computing WebGPU.

Gli analisti di calcolo offrono maggiori opportunità di condividere i dati e di fornire i risultati di calcolo all'interno di gruppi di variatori che lavorano per migliorare l'efficienza. Questo può portare a miglioramenti significativi rispetto ai precedenti tentativi di utilizzare WebGL per lo stesso scopo.

Come esempio dei miglioramenti in termini di efficienza che ciò può portare, una porta iniziale di un modello di diffusione delle immagini in TensorFlow.js mostra un guadagno di prestazioni 3 volte superiore su diversi hardware quando si passa da WebGL a WebGPU. Su alcuni componenti hardware testati, il rendering dell'immagine è stato eseguito in meno di 10 secondi. Siccome si trattava di una versione precedente, riteniamo che siano possibili ulteriori miglioramenti sia in WebGPU che in TensorFlow.js. Dai un'occhiata a Novità del 2023 sul Web ML sessione Google I/O.

Tuttavia, WebGPU non solo consente di portare sul web le funzionalità delle GPU.

Progettato prima per JavaScript

Le funzionalità che consentono questi casi d'uso sono disponibili da tempo per gli sviluppatori di computer e dispositivi mobili specifici per piattaforma, quindi si è tenuta una sfida a presentarle in un modo che sembri parte naturale della piattaforma web.

WebGPU è stata sviluppata tenendo conto di oltre un decennio di sviluppatori che hanno svolto un lavoro straordinario con WebGL. Siamo stati in grado di gestire i problemi riscontrati, i colli di bottiglia che hanno riscontrato e i problemi sollevati, per incanalare tutti questi feedback nella nuova API.

Abbiamo visto che il modello a stato globale di WebGL ha reso la creazione di applicazioni e librerie solide e componibili difficile e fragile. Di conseguenza, WebGPU riduce drasticamente la quantità di stato di cui gli sviluppatori devono tenere traccia durante l'invio dei comandi della GPU.

Abbiamo saputo che eseguire il debug delle applicazioni WebGL è stato un problema, pertanto WebGPU include meccanismi di gestione degli errori più flessibili che non influiscono negativamente sulle tue prestazioni. Inoltre, abbiamo fatto di tutto per garantire che ogni messaggio che ricevi dall'API sia facile da capire e usare.

Abbiamo anche notato che spesso il sovraccarico dovuto a troppe chiamate JavaScript era un collo di bottiglia per applicazioni WebGL complesse. Di conseguenza, l'API WebGPU è meno efficiente e puoi ottenere di più con meno chiamate di funzione. Ci concentriamo sull'esecuzione di una convalida pesante in anticipo, mantenendo il loop di disegno critico il più agevole possibile. Inoltre, offriamo nuove API, come i render bundle, che consentono di registrare in anticipo un gran numero di comandi di disegno e di ripeterli con una singola chiamata.

Per dimostrare l'enorme differenza che può fare una funzionalità come i bundle di rendering, ecco un'altra demo di Babylon.js. Il renderer WebGL 2 è in grado di eseguire tutte le chiamate JavaScript per eseguire il rendering di questa scena della galleria d'arte circa 500 volte al secondo. Il che va benissimo!

La galleria d'arte

Il renderer WebGPU, tuttavia, attiva una funzionalità chiamata Rendering snapshot. Basato sui bundle di rendering WebGPU, questa funzionalità consente di inviare la stessa scena a una velocità 10 volte superiore. Questo sovraccarico ridotto consente a WebGPU di eseguire il rendering di scene più complesse, consentendo allo stesso tempo alle applicazioni di fare di più con JavaScript in parallelo.

Le API grafiche moderne sono note per la complessità e per la semplicità di trading che offrono opportunità di ottimizzazione estreme. WebGPU, invece, è incentrato sulla compatibilità multipiattaforma, gestendo automaticamente nella maggior parte dei casi argomenti tradizionalmente difficili, come la sincronizzazione delle risorse.

Questo ha l'effetto positivo sul fatto che WebGPU è facile da imparare e usare. Si basa sulle funzionalità esistenti della piattaforma web per elementi come il caricamento di immagini e video e si affida a pattern JavaScript ben noti come Promises per le operazioni asincrone. Ciò consente di mantenere al minimo la quantità di codice boilerplate necessaria. Puoi visualizzare il tuo primo triangolo sullo schermo in meno di 50 righe di codice.

<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>

Conclusione

È emozionante vedere tutte le nuove possibilità che WebGPU offre sulla piattaforma web e non vediamo l'ora di scoprire tutti i nuovi, fantastici casi d'uso che troverai per WebGPU.

attorno a WebGL è stato sviluppato un vivace ecosistema di librerie e framework che non vede l'ora di adottare WebGPU. Il supporto di WebGPU è in corso o già completo in molte librerie WebGL JavaScript popolari e, in alcuni casi, sfruttare i vantaggi di WebGPU potrebbe essere semplice come modificare un singolo flag.

Babylon.js, Build 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js e Unity.
Framework, applicazioni e librerie con porte WebGPU complete o in corso.

E questa prima release in Chrome 113 è solo un inizio. Sebbene la nostra release iniziale sia per Windows, ChromeOS e MacOS, prevediamo di rendere disponibile WebGPU sulle altre piattaforme, come Android e Linux, nel prossimo futuro.

Non è solo il team di Chrome a lavorare al lancio di WebGPU. Le implementazioni sono in corso anche in Firefox e WebKit.

Inoltre, presso W3C sono già in fase di progettazione nuove funzionalità che possono essere esposte quando disponibili nell'hardware. Ad esempio, in Chrome prevediamo di attivare a breve il supporto per i numeri in virgola mobile a 16 bit negli shardr e la classe di istruzioni DP4a per ulteriori miglioramenti delle prestazioni del machine learning.

WebGPU è un'API completa che sblocca prestazioni straordinarie se investi in questa API. Oggi ne abbiamo parlato solo a un livello generale, ma se vuoi iniziare a usare WebGPU, dai un'occhiata al nostro codelab introduttivo, La tua prima app WebGPU. In questo codelab, creerai una versione GPU del classico Game of Life di Conway. Questo codelab ti guida passo passo nella procedura, così puoi provarlo anche se è la prima volta che esegui lo sviluppo della GPU.

Anche i campioni di WebGPU sono un buon posto per avere un'idea dell'API. Variano dal tradizionale "triangolo ciao" a pipeline di rendering e calcolo più complete, dimostrando una varietà di tecniche. Infine, consulta le altre nostre risorse.