WebGPU: sblocco dell'accesso alle GPU moderne nel browser

Scopri come WebGPU sblocca la potenza della GPU per prestazioni di machine learning più veloci e un migliore rendering della grafica.

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

La nuova API WebGPU consente di aumentare notevolmente le prestazioni dei 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 è disponibile 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 3D e altro ancora. WebGL si basa sulla famiglia di API OpenGL, sviluppata per la prima volta nel 1992. È passato molto 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 ed impegnativi per la programmazione delle GPU, come l'esplosione del machine learning e i progressi negli algoritmi di rendering. WebGPU è il successore di WebGL e porta i progressi di questa nuova classe di API moderne sul web.

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 è parte integrante del gruppo "GPU for the Web" di W3C dal 2017 ed è frutto della collaborazione tra molte aziende come Apple, Google, Mozilla, Microsoft e Intel. E ora, dopo 6 anni di lavoro, siamo felici di annunciare che una delle più importanti aggiunte alla piattaforma web è finalmente disponibile.

WebGPU è attualmente disponibile in Chrome 113 su ChromeOS, macOS e Windows, con altre piattaforme presto disponibili. Un enorme ringraziamento agli altri collaboratori di Chromium e Intel in particolare che hanno contribuito a realizzare questo obiettivo.

Ora diamo un'occhiata ad alcuni degli interessanti casi d'uso abilitati da WebGPU.

Sblocca nuovi carichi di lavoro GPU per il rendering

Le funzionalità WebGPU, come gli shader di computing, consentono il trasferimento di nuove classi di algoritmi sulla GPU. Ad esempio, algoritmi in grado di aggiungere dettagli più dinamici alle scene, simulare fenomeni fisici e altro ancora. Anche i carichi di lavoro che in precedenza potevano essere eseguiti solo in JavaScript, ora possono essere spostati nella GPU.

Il seguente video mostra l'algoritmo dei cubi in marcia utilizzato per triangolare la superficie di queste metaball. Nei primi 20 secondi del video, l'algoritmo, quando è in esecuzione in JavaScript, fa fatica a tenere il passo con la pagina in esecuzione solo a 8 f/s, il che genera un'animazione insolita. Per mantenere le prestazioni in JavaScript dobbiamo abbassare molto il livello di dettaglio.

C'è una differenza tra il giorno e la notte quando lo stesso algoritmo viene trasferito a un computing shaker, che appare nel video dopo 20 secondi. Le prestazioni migliorano drasticamente, con la pagina ora in esecuzione a una velocità di 60 f/s e c'è ancora molto margine 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 effetti visivi complessi che prima non erano pratici. Nel seguente esempio, creato nella popolare libreria Babylon.js, la superficie dell'oceano viene simulata interamente sulla GPU. Le dinamiche realistiche sono create da molte onde indipendenti che vengono aggiunte l'una all'altra. Ma simulare direttamente ogni onda sarebbe troppo costoso.

Demo sull'oceano

Ecco perché la demo utilizza un algoritmo avanzato chiamato Fast Fourier Transform. Anziché rappresentare tutte le onde come dati di posizione complessi, in questo modo vengono utilizzati i dati spettrali, che sono molto più efficienti nell'esecuzione dei calcoli. Quindi ogni frame usa la trasformazione di Fourier per convertire i dati spettrali nei dati posizionali che rappresenta 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 riproposto 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 come modo per iniziare i calcoli e di pacchettizzare e decomprimere con attenzione i dati dei tensori nella texture anziché accessi 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 codice alle aspettative di un'API progettata solo per il disegno. In combinazione con la 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 Shaper Compute sono la nuova funzionalità principale di WebGPU e rimuovono questi punti critici. 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 Shader di computing WebGPU, tra cui carichi di memoria condivisa, calcoli condivisi e scritture flessibili sulla memoria.
. Efficienza dello shaker di WebGPU

I bilanciatori del carico offrono maggiori opportunità di condivisione dei dati e dei risultati dei calcoli all'interno di gruppi di strumenti per una maggiore efficienza. Ciò può comportare notevoli guadagni rispetto ai precedenti tentativi di utilizzare WebGL per lo stesso scopo.

Ad esempio, la porta iniziale di un modello di diffusione delle immagini in TensorFlow.js mostra un guadagno in termini di prestazioni 3 volte superiore su una varietà 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. Dai un'occhiata a Novità sul web ML nel 2023 sessione Google I/O.

Ma WebGPU non serve solo a portare le funzionalità delle GPU sul web.

Progettato inizialmente per JavaScript

Le funzionalità che permettono questi casi d'uso sono da un po' a disposizione degli sviluppatori di dispositivi mobili e desktop per piattaforme specifiche, ed è stata per noi la sfida di mostrarle in un modo che sembri parte integrante della piattaforma web.

WebGPU è stato sviluppato con il beneficio del senno di poi da oltre un decennio di sviluppatori che lavorano in modo eccezionale 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 visto che il modello di stato globale di WebGL rendeva difficile e delicata la creazione di librerie e applicazioni robuste e componibili. Quindi WebGPU riduce drasticamente la quantità di stato di cui gli sviluppatori devono tenere traccia durante l'invio dei comandi GPU.

Abbiamo sentito dire che il debug delle applicazioni WebGL era complicato, quindi WebGPU include meccanismi di gestione degli errori più flessibili che non influiscono sulle tue 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 efficiente, quindi puoi ottenere di più con meno chiamate di funzione. Ci concentriamo sull'esecuzione anticipata di convalida pesante, mantenendo l'anello 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 l'enorme differenza che può fare una funzionalità come i bundle di rendering, ecco un'altra demo di Babylon.js. Il renderer WebGL 2 può eseguire tutte le chiamate JavaScript per eseguire il rendering di questa scena di una 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 delle 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 sono note per la complessità e la semplicità di trading per opportunità di ottimizzazione estreme. WebGPU, d'altra parte, si concentra sulla compatibilità multipiattaforma, gestendo argomenti tradizionalmente difficili come la sincronizzazione automatica delle risorse nella maggior parte dei casi.

Questo ha il felice effetto collaterale che WebGPU è facile da imparare e usare. Si basa sulle funzionalità esistenti della piattaforma web per, ad esempio, il caricamento di immagini e video e si affida a pattern JavaScript noti come Promises per le operazioni asincrone. In questo modo è possibile ridurre al minimo la quantità di codice boilerplate. 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à offerte da WebGPU alla piattaforma web e non vediamo l'ora di vedere tutti i nuovi e interessanti casi d'uso che troverai per WebGPU.

Un vivace ecosistema di librerie e framework è stato costruito attorno a WebGL e questo stesso ecosistema non vede l'ora 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, Build 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js e Unity.
Framework, applicazioni e librerie con porte WebGPU completate o attive.

E questa prima release di Chrome 113 è solo un inizio. Anche se la nostra release iniziale è per Windows, ChromeOS e MacOS, prevediamo di portare WebGPU sulle piattaforme rimanenti 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, nel 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 per i numeri in virgola mobile a 16 bit negli streamr 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 a usare WebGPU, dai un'occhiata al nostro codelab introduttivo, La tua prima app WebGPU. In questo codelab, creerai una versione GPU del classico gioco della vita di Conway. Questo codelab ti guida passo passo nella procedura, così potrai provarla anche se è la prima volta che esegui lo sviluppo di una GPU.

Anche gli esempi di WebGPU sono un buon punto di partenza per avere un'idea dell'API. che vanno dal tradizionale "triangolo ciao" per completare le pipeline di rendering e calcolo, con una dimostrazione di una varietà di tecniche. Infine, dai un'occhiata alle altre risorse.