WebGPU:在瀏覽器中解鎖現(xiàn)代 GPU 訪問
近日,Chrome 支持了 WebGPU,新的 WebGPU API 在圖形和機(jī)器學(xué)習(xí)工作負(fù)載方面實(shí)現(xiàn)了巨大的性能提升。本文將探討 WebGPU 如何改進(jìn)當(dāng)前 WebGL 解決方案,并展望未來的發(fā)展方向。
WebGPU 背景
WebGL 于 2011 年登陸 Chrome。通過允許 Web 應(yīng)用利用 GPU,WebGL 可以在 Web 上實(shí)現(xiàn)驚人的體驗(yàn)——從 Google 地球到交互式音樂視頻,再到 3D 房地產(chǎn)等等。WebGL是基于OpenGL系列API開發(fā)的,該API最初開發(fā)于1992年,自那時(shí)以來 GPU 硬件已經(jīng)發(fā)生了極大的變化。
為跟上這一進(jìn)步,一種新型的API被開發(fā)出來,以更高效地與現(xiàn)代GPU硬件交互。這些API包括Direct3D 12、Metal和Vulkan。這些新的 API 支持GPU編程的新的和苛刻的用例,例如機(jī)器學(xué)習(xí)的爆炸式增長(zhǎng)和渲染算法的進(jìn)步。WebGPU 是 WebGL 的繼承者,將這種新型現(xiàn)代 API 的進(jìn)步帶到了 Web。
WebGPU 在瀏覽器中解鎖了許多新的 GPU 編程可能性。它更好地反映了現(xiàn)代 GPU 硬件的工作方式,并為未來更高級(jí)的GPU功能奠定了基礎(chǔ)。自2017年以來,這個(gè)API已經(jīng)在W3C的“Web GPU”小組中不斷完善,并得到了包括蘋果、谷歌、Mozilla、微軟和英特爾在內(nèi)的眾多公司的合作。經(jīng)過 6 年的努力,很高興地宣布,這項(xiàng)對(duì) Web 平臺(tái)最大的增強(qiáng)功能終于可用了!
WebGPU 現(xiàn)在可以在 Chrome OS、macOS和Windows上的Chrome 113中使用,其他平臺(tái)也將會(huì)很快推出。
下面來看一些令人興奮的 WebGPU 使用案例。
解鎖用于渲染的新 GPU 工作負(fù)載
諸如計(jì)算著色器之類的 WebGPU 功能使新類別的算法能夠移植到 GPU 上。例如,可以為場(chǎng)景添加更多動(dòng)態(tài)細(xì)節(jié)、模擬物理現(xiàn)象等算法!甚至以前只能用 JavaScript 完成的工作負(fù)載現(xiàn)在可以轉(zhuǎn)移到 GPU 上。
以下視頻顯示了用于對(duì)這些元球表面進(jìn)行三角測(cè)量的行進(jìn)立方體算法。在視頻的前 20 秒內(nèi),當(dāng)該算法在 JavaScript 中運(yùn)行時(shí),它很難跟上僅以 8 FPS 運(yùn)行的頁面,從而導(dǎo)致動(dòng)畫卡頓。為了在 JavaScript 中保持高性能,需要大量降低細(xì)節(jié)級(jí)別。
當(dāng)我們將相同的算法移動(dòng)到計(jì)算著色器時(shí),這是一個(gè)白天和黑夜的區(qū)別,這在 20 秒后的視頻中可以看到。性能顯著提高,頁面現(xiàn)在以 60 FPS 的流暢速度運(yùn)行,并且對(duì)于其他效果仍有很大的性能提升空間。此外,頁面的主要 JavaScript 循環(huán)完全釋放出來用于其他任務(wù),確保與頁面的交互保持響應(yīng)。
WebGPU 還可以實(shí)現(xiàn)以前不實(shí)用的復(fù)雜視覺效果。在以下示例中,在流行的 Babylon.js 庫中創(chuàng)建,海洋表面完全在 GPU 上模擬。逼真的動(dòng)態(tài)是由許多相互添加的獨(dú)立波創(chuàng)建的。但是直接模擬每個(gè)波浪太昂貴了。
這就是演示使用稱為快速傅立葉變換的高級(jí)算法的原因。這不是將所有波表示為復(fù)雜的位置數(shù)據(jù),而是使用更有效地執(zhí)行計(jì)算的光譜數(shù)據(jù)。然后每一幀使用傅立葉變換將光譜數(shù)據(jù)轉(zhuǎn)換為代表波浪高度的位置數(shù)據(jù)。
更快的 ML 推理
WebGPU 還可用于加速機(jī)器學(xué)習(xí),這已成為近年來 GPU 的主要用途。
長(zhǎng)期以來,創(chuàng)發(fā)人員一直在重新利用 WebGL 的渲染 API 來執(zhí)行非渲染操作,例如機(jī)器學(xué)習(xí)計(jì)算。然而,這需要繪制三角形的像素作為啟動(dòng)計(jì)算的一種方式,并仔細(xì)打包和解包紋理中的張量數(shù)據(jù),而不是更通用的內(nèi)存訪問。
以這種方式使用 WebGL 需要開發(fā)人員笨拙地使他們的代碼符合專為繪圖而設(shè)計(jì)的 API 的期望。再加上缺乏計(jì)算之間的共享內(nèi)存訪問等基本功能,這會(huì)導(dǎo)致重復(fù)工作和次優(yōu)性能。
計(jì)算著色器是 WebGPU 的主要新功能,可以消除這些痛點(diǎn)。計(jì)算著色器提供更靈活的編程模型,利用 GPU 的大規(guī)模并行特性,同時(shí)不受嚴(yán)格的渲染操作結(jié)構(gòu)的限制。
計(jì)算著色器為在著色器工作組內(nèi)共享數(shù)據(jù)和計(jì)算結(jié)果提供了更多機(jī)會(huì),以提高效率。與之前出于相同目的使用 WebGL 的嘗試相比,這可能會(huì)帶來顯著的收益。
作為這可以帶來的效率提升的一個(gè)例子,TensorFlow.js 中圖像擴(kuò)散模型的初始端口顯示,當(dāng)從 WebGL 移動(dòng)到 WebGPU 時(shí),各種硬件的性能提升了 3 倍。在一些測(cè)試過的硬件上,圖像渲染時(shí)間不到 10 秒。因?yàn)檫@是一個(gè)早期的端口,相信 WebGPU 和 TensorFlow.js 都有更多改進(jìn)的可能!
但 WebGPU 不僅僅是將 GPU 功能帶到 Web 上。
首先為 JavaScript 設(shè)計(jì)
WebGPU是在對(duì)WebGL開發(fā)人員十年的工作經(jīng)驗(yàn)進(jìn)行反思的基礎(chǔ)上開發(fā)的。將他們遇到的問題、遇到的瓶頸和提出的問題整理出來,并將所有反饋匯總到這個(gè)新的API中。
WebGL 的全局狀態(tài)模型使得創(chuàng)建強(qiáng)大、可組合的庫和應(yīng)用變得困難和脆弱。因此,WebGPU大大減少了開發(fā)人員需要跟蹤GPU命令時(shí)需要跟蹤的狀態(tài)數(shù)量。
調(diào)試 WebGL 應(yīng)用是很痛苦的,因此WebGPU包括了更靈活的錯(cuò)誤處理機(jī)制,不會(huì)降低性能。而且確保從API中獲得的每條消息都易于理解和可操作。
頻繁調(diào)用過多的 JavaScript 函數(shù)會(huì)成為復(fù)雜 WebGL 應(yīng)用的瓶頸。因此,WebGPU API 的通信量較少,因此可以用更少的函數(shù)調(diào)用完成更多的任務(wù)。專注于在前期執(zhí)行重量級(jí)驗(yàn)證,盡可能使關(guān)鍵的繪制循環(huán)精簡(jiǎn)。提供了像渲染捆綁一類的新 API,它允許預(yù)先記錄大量的繪圖命令,并以單個(gè)調(diào)用重播它們。
為了展示像渲染捆綁這樣一個(gè)功能會(huì)帶來多么大的變化,下面是Babylon.js的另一個(gè)演示。他們的 WebGL 2 渲染器可以每秒執(zhí)行約 500次 JavaScript 調(diào)用以呈現(xiàn)這個(gè)美術(shù)館場(chǎng)景。
然而,他們的 WebGPU 渲染器啟用了一項(xiàng)稱為快照渲染的功能。此功能構(gòu)建在 WebGPU 渲染包之上,可使提交相同場(chǎng)景的速度提高 10 倍以上。這種顯著減少的開銷使 WebGPU 能夠呈現(xiàn)更復(fù)雜的場(chǎng)景,同時(shí)還允許應(yīng)用使用 JavaScript 并行執(zhí)行更多操作。
現(xiàn)代圖形 API 以復(fù)雜性、以簡(jiǎn)單性換取極端優(yōu)化機(jī)會(huì)而著稱。另一方面,WebGPU 專注于跨平臺(tái)兼容性,在大多數(shù)情況下自動(dòng)處理資源同步等傳統(tǒng)難題。
WebGPU 易于學(xué)習(xí)和使用。它依賴于網(wǎng)絡(luò)平臺(tái)的現(xiàn)有功能來進(jìn)行圖像和視頻加載等操作,并依賴于眾所周知的 JavaScript 模式,例如用于異步操作的 Promises。這有助于將所需的樣板代碼數(shù)量保持在最低限度??梢杂貌坏?50 行代碼在屏幕上顯示第一個(gè)三角形。
<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>
總結(jié)
很高興看到 WebGPU 為 Web 平臺(tái)帶來的所有新可能性,圍繞 WebGL 構(gòu)建了一個(gè)充滿活力的庫和框架生態(tài)系統(tǒng),并且同樣的生態(tài)系統(tǒng)渴望擁抱 WebGPU。在許多流行的 Javascript WebGL 庫中,對(duì) WebGPU 的支持正在進(jìn)行中或已經(jīng)完成,在某些情況下,利用 WebGPU 的優(yōu)勢(shì)可能就像更改單個(gè)標(biāo)志一樣簡(jiǎn)單!
Chrome 113 中的第一個(gè)版本只是一個(gè)開始。雖然初始版本適用于 Windows、ChromeOS 和 MacOS,但計(jì)劃在不久的將來將 WebGPU 引入其余平臺(tái),如 Android 和 Linux。
致力于推出 WebGPU 的不僅僅是 Chrome 團(tuán)隊(duì)。Firefox 和 WebKit 的實(shí)現(xiàn)也在進(jìn)行中。
此外,W3C 已經(jīng)在設(shè)計(jì)新功能,這些功能在硬件可用時(shí)可以公開。例如:在 Chrome 中,計(jì)劃很快在著色器和 DP4 類指令中啟用對(duì) 16 位浮點(diǎn)數(shù)的支持,以進(jìn)一步提高機(jī)器學(xué)習(xí)性能。
WWebGPU是一個(gè)廣泛的API,其以釋放驚人的性能。本文只能對(duì)其優(yōu)點(diǎn)進(jìn)行概述,但如果想親身體驗(yàn)WebGPU,可以查看入門 Codelab《Your first WebGPU app[1]》,將構(gòu)建經(jīng)典康威生命游戲的GPU版本。這個(gè) Codelab 會(huì)逐步引導(dǎo)完成整個(gè)過程,因此即使第一次進(jìn)行GPU開發(fā),也可以輕松嘗試。
參考:https://developer.chrome.com/blog/webgpu-io2023/
相關(guān)鏈接
[1]Your first WebGPU app: https://codelabs.developers.google.com/your-first-webgpu-app