WebGPU: sblocco dell'accesso alle GPU moderne nel browser

Scopri come WebGPU sblocca la potenza della GPU per un rendimento più rapido del machine learning e un rendering grafico migliore.

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

La nuova API WebGPU offre enormi miglioramenti delle prestazioni nei carichi di lavoro di grafica e machine learning. Questo articolo spiega in che modo WebGPU rappresenta un miglioramento rispetto all'attuale soluzione WebGL, con un'anticipazione degli sviluppi futuri. Prima però, forniamo un po' di contesto sul motivo per cui è stato sviluppato WebGPU.

Contesto su WebGPU

WebGL è stato introdotto in Chrome nel 2011. Consentendo alle applicazioni web di sfruttare le GPU, WebGL offre esperienze straordinarie sul web, da Google Earth ai video musicali interattivi, alle procedure dettagliate di immobili in 3D e altro ancora. WebGL si basa sulla famiglia di API OpenGL sviluppata per la prima volta nel 1992. È successo tanto tempo fa. Puoi immaginare che l'hardware della GPU si sia evoluto in modo significativo da allora.

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

WebGPU sblocca molte nuove possibilità di programmazione delle GPU nel browser. Riflette meglio il funzionamento dell'hardware GPU moderno, gettando al contempo le basi per funzionalità GPU più avanzate in futuro. L'API è in fase di sviluppo nel gruppo "GPU per il web" del W3C dal 2017 ed è frutto della collaborazione di molte aziende come Apple, Google, Mozilla, Microsoft e Intel. Ora, dopo 6 anni di lavoro, siamo lieti di annunciare che una delle più grandi aggiunte alla piattaforma web è finalmente disponibile.

WebGPU è già disponibile in Chrome 113 su ChromeOS, macOS e Windows e sarà presto disponibile su altre piattaforme. Un enorme grazie agli altri collaboratori di Chromium e in particolare a Intel che hanno contribuito a realizzare tutto questo.

Ora diamo un'occhiata ad alcuni dei fantastici casi d'uso abilitati da WebGPU.

Sblocca nuovi carichi di lavoro GPU per il rendering

Le funzionalità WebGPU, come gli shader di calcolo, consentono di eseguire il porting di nuove classi di algoritmi sulla GPU. Ad esempio, algoritmi che possono aggiungere dettagli più dinamici alle scene, simulare fenomeni fisici e altro ancora. Esistono persino carichi di lavoro che in precedenza potevano essere eseguiti solo in JavaScript, ma che ora possono essere spostati sulla GPU.

Il seguente video mostra l'algoritmo marching cubes utilizzato per triangolare la superficie di queste metaball. Nei primi 20 secondi del video, l'algoritmo, quando viene eseguito in JavaScript, fatica a tenere il passo con la pagina che funziona a soli 8 FPS, con un risultato di animazione a scatti. Per mantenere le prestazioni in JavaScript, dovremmo abbassare notevolmente il livello di dettagli.

C'è una differenza abissale quando spostiamo lo stesso algoritmo in un compute shader, come si vede nel video dopo 20 secondi. Il rendimento migliora notevolmente, poiché la pagina ora funziona a 60 FPS fluidi e c'è ancora molto spazio per altri effetti. Inoltre, il loop JavaScript principale della pagina viene completamente liberato per altre attività, garantendo che le interazioni con la pagina rimangano reattive.

Demo delle metaball

WebGPU consente inoltre di utilizzare effetti visivi complessi che 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 vengono create dall'aggiunta di molte onde indipendenti. Tuttavia, simulare direttamente ogni onda sarebbe troppo costoso.

La demo dell'oceano

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 sono molto più efficienti per eseguire i calcoli. Poi ogni frame utilizza la trasformata di Fourier per convertire i dati spettrali in dati di posizione che rappresentano l'altezza delle onde.

Inferenza ML più veloce

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à hanno riutilizzato l'API di rendering di WebGL per eseguire operazioni non di rendering come i calcoli di machine learning. Tuttavia, questo richiede di disegnare i pixel dei triangoli per avviare i calcoli e imballare e sballare con attenzione i dati tensori nella texture anziché accedere alla memoria per scopi più generali.

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.
Un'unica esecuzione di un operatore ML con WebGL.

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

Gli shader di calcolo sono la nuova funzionalità principale di WebGPU e rimuovono questi problemi. I responsabili di computing offrono un modello di programmazione più flessibile che sfrutta la natura altamente parallela della GPU senza essere vincolati dalla struttura rigida delle operazioni di rendering.

I vari miglioramenti dell'efficienza negli Shar di computing WebGPU, tra cui carichi di memoria condivisa, calcoli condivisi e scritture flessibili sulla memoria.
Efficienze degli shader di calcolo WebGPU.

Gli shader di calcolo offrono maggiori opportunità per condividere dati e risultati di calcolo all'interno di gruppi di lavoro degli shader per una maggiore efficienza. Ciò può portare a vantaggi significativi rispetto ai tentativi precedenti di utilizzare WebGL per lo stesso scopo.

Come esempio degli incrementi di efficienza che questo può comportare, una porta iniziale di un modello di diffusione di immagini in TensorFlow.js mostra un incremento del rendimento di 3 volte su una serie di hardware quando si passa da WebGL a WebGPU. Su alcuni hardware testati, il rendering dell'immagine è stato eseguito in meno di 10 secondi. Poiché si tratta di una delle prime porte, riteniamo che siano possibili ulteriori miglioramenti sia in WebGPU che in TensorFlow.js. Consulta l'articolo Novità dell'AI su web nel 2023. Sessione Google I/O.

Ma WebGPU non si limita a portare le funzionalità della GPU sul web.

Progettato per JavaScript

Le funzionalità che consentono questi casi d'uso sono disponibili da tempo per gli sviluppatori di app mobile e desktop specifici della piattaforma ed è stata la nostra sfida esporle in modo che sembrino una parte naturale della piattaforma web.

WebGPU è stato sviluppato con il vantaggio di poter fare tesoro dell'esperienza di oltre un decennio di sviluppatori che hanno svolto un lavoro straordinario con WebGL. Abbiamo potuto includere i problemi riscontrati, i colli di bottiglia riscontrati e i problemi sollevati e incanalato tutti i feedback in questa nuova API.

Abbiamo notato che il modello di stato globale di WebGL rendeva difficile e fragile la creazione di librerie e applicazioni composibili e robuste. Quindi WebGPU riduce drasticamente la quantità di stato di cui gli sviluppatori devono tenere traccia durante l'invio dei comandi GPU.

Ci è stato detto che il debug delle applicazioni WebGL era un problema, quindi WebGPU include meccanismi di gestione degli errori più flessibili che non influiscono sulle prestazioni. Inoltre, abbiamo fatto di tutto per assicurarci che ogni messaggio che ricevi dall'API sia facile da capire e utilizzabile.

Abbiamo anche notato che spesso l'overhead associato a un numero eccessivo di chiamate JavaScript rappresentava un collo di bottiglia per applicazioni WebGL complesse. Di conseguenza, l'API WebGPU è meno chiacchierona, quindi puoi fare di più con meno chiamate di funzione. Ci concentriamo sull'esecuzione di una convalida complessa in anticipo, mantenendo il ciclo di disegno critico il più snello possibile. Inoltre, offriamo nuove API, come i render bundle, che consentono di registrare in anticipo un numero elevato di comandi di disegno e di ripeterli con una singola chiamata.

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

La galleria d'arte

Tuttavia, il renderer WebGPU attiva una funzionalità chiamata Rendering snapshot. Basata sui bundle di rendering WebGPU, questa funzionalità consente di inviare la stessa scena più di 10 volte più velocemente. Questo overhead notevolmente ridotto consente a WebGPU di eseguire il rendering di scene più complesse, consentendo al contempo alle applicazioni di fare di più con JavaScript in parallelo.

Le API grafiche moderne hanno la reputazione di essere complesse, perché scambiano la semplicità per opportunità di ottimizzazione estreme. WebGPU, invece, si concentra sulla compatibilità multipiattaforma e gestisce automaticamente nella maggior parte dei casi argomenti tradizionalmente difficili come la sincronizzazione delle risorse.

Il vantaggio è che WebGPU è facile da imparare e utilizzare. Si basa sulle funzionalità esistenti della piattaforma web per operazioni come il caricamento di immagini e video e si basa su pattern JavaScript ben noti come le promesse per le operazioni asincrone. In questo modo, la quantità di codice boilerplate necessaria viene ridotta al minimo. 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

È entusiasmante vedere tutte le nuove possibilità offerte da WebGPU alla piattaforma web e non vediamo l'ora di scoprire tutti i nuovi casi d'uso che troverete per WebGPU.

Intorno a WebGL è stato creato un ecosistema vivace di librerie e framework, che è ansioso di adottare WebGPU. Il supporto per WebGPU è in corso o è già completo in molte librerie JavaScript JavaScript più diffuse e in alcuni casi sfruttare i vantaggi di WebGPU potrebbe essere semplice come modificare un singolo flag.

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

E questa prima release di Chrome 113 è solo un inizio. La nostra release iniziale è per Windows, ChromeOS e macOS, ma prevediamo di portare WebGPU alle altre piattaforme come Android e Linux nel prossimo futuro.

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

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

WebGPU è un'API completa che consente di ottenere prestazioni straordinarie se investi. Oggi possiamo illustrarne i vantaggi solo a livello generale, ma se vuoi iniziare con 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 illustra la procedura passo passo, quindi puoi provarla anche se è la prima volta che sviluppi per GPU.

Anche gli esempi di WebGPU sono un buon punto di partenza per avere un'idea dell'API. Vanno dal tradizionale "triangolo di saluto" a pipeline di rendering e calcolo più complete, che dimostrano una serie di tecniche. Infine, consulta le nostre altre risorse.