关注「索引目录」公众号,获取更多干货。
多年来,JavaScript一直是Web的主要语言。它的流行程度可能甚至让它的创造者Brendan Eich都感到惊讶,据说他只用了一周左右的时间就构建了该语言的第一个版本。
JavaScript之所以能占据主导地位,其中一个重要原因在于浏览器的强大功能。我们只需通过浏览器这一个应用程序,就能访问数亿个网站和应用程序,无需下载或安装任何软件。这正是其成功的关键所在。
浏览器厂商一直在不遗余力地提升 JavaScript 的速度。现代引擎已经过高度优化。但仍然存在一个根本性的限制:
JavaScript 在 CPU 上运行。
那么,哪些任务最适合用GPU来完成呢?
这就是WebGPU 的用武之地。🚀
让我们来看看它究竟能做什么,以及何时才是真正适合使用它的时候。
顺便一提——我的jsDay演讲越来越近了!我将在演讲中谈到 **WebGPU + WebAssembly** ,这正是你在本文中看到的:浏览器中的 GPU、计算着色器,以及将 Web 推向比以往更远的地方。
为了庆祝(也可能是为了稍微缓解一下我会前的紧张情绪😅),我录制了一个演讲的宣传短片,你可以在这里找到。
如果你愿意观看并点个赞,我会非常感激。
如果你来参加 **jsDay** ,演讲结束后欢迎来打个招呼! 🙂
开始前的简要说明
我已经在另一篇文章中介绍过 WebGPU,所以这里就不再赘述了:
为什么说 WebGPU 代表着 Web 的未来(现场演示)
但我们先简要回顾一下一件重要的事情。
WebGPU 不仅仅关乎图形处理——尽管它的图形处理能力非常出色。
它还赋予了我们极其强大的功能:
访问GPU计算资源。
CPU 与 GPU(快速回顾)
这一点对你们大多数人来说显而易见,但我们还是为初学者和那些大学第一学期都在睡觉的人做一个简单的区分:
CPU非常擅长连续执行一些复杂的任务。
在浏览器中,这通常意味着执行JavaScript 或 WebAssembly 代码。
GPU非常擅长大规模并行执行简单的任务。
而在浏览器中,让我们能够使用 GPU 的 API 就是WebGPU。
这就是为什么 GPU 非常擅长执行需要重复数千次或数百万次相同操作的任务。
我想亲自测试一下。
如果你经常看我的帖子,你可能知道我不喜欢盲目相信别人,我更喜欢亲身尝试。🙂
所以我开发了一个小型应用程序,用于测试JavaScript 与 WebGPU 的性能。
这些并非那种在不同系统中逐行实现完全相同算法的超学术性基准测试。多亏了它们,我可能拿不到麻省理工的博士学位。😅
相反,我尝试了一种更实际的方法:
我测试了两种技术在以各自的自然方式解决同一问题时的表现,并没有刻意偏袒任何一种技术。
您可以在这里探索所有内容:
GitHub 仓库
https://github.com/sylwia-lask/webgpu-bench
在线演示
WebGPU Bench
欢迎您亲自体验一下。😄
场景 1 — 粒子模拟
第一个测试是粒子模拟。
如果你在网上阅读有关 WebGPU 的内容——或者询问 ChatGPT——这通常会被视为 GPU 优越性的经典例子。
每个粒子都具有两个属性:
-
位置 (x, y) -
速度 (vx, vy)
每一帧我们都这样更新:
x = x + vx
y = y + vy
如果粒子撞到屏幕边缘,我们就反转速度来模拟反弹。
伪代码:
for each particle:
pos += vel
if pos.x < 0 or pos.x > width:
vel.x = -vel.x
if pos.y < 0 or pos.y > height:
vel.y = -vel.y
因此,计算着色器实际上执行类似以下的操作:
pos += vel
这基本上是每个粒子进行两次浮点数加法运算(外加一次反弹检查)。
结果
令人惊讶的是…… JavaScript 和 WebGPU 实现之间几乎没有区别。两个版本产生的帧率非常接近。
与此同时,WebGPU 版本需要编写更多的样板代码。
为什么会发生这种情况?
1️⃣ 该算法极其简单
粒子更新每个线程仅执行 2-4 次浮点运算。
GPU 在计算密集型任务中才能真正发挥优势,而不是在这种轻量级任务中。
2️⃣ Canvas 2D 最终也会在 GPU 上进行处理
这是很多前端开发人员没有意识到的。
即使使用Canvas 2D,浏览器通常也会使用 GPU 加速进行渲染。
Chrome 或 Edge 等浏览器内部使用Skia或Dawn等系统,最终向 GPU 发出绘制调用。
因此,在实践中:
-
WebGPU → 直接与 GPU 通信 -
Canvas 2D → 浏览器会自动与 GPU 通信
而且该浏览器针对此类应用进行了非常好的优化fillRect()。
所以 CPU 版本并不像人们通常认为的那样“仅限 CPU 使用”。
GPU能否胜出?
或许可以——但前提是我们得让模拟变得更复杂。
例如,像n体引力这样的问题,其中每个粒子都吸引其他所有粒子。这将极大地增加数学运算量。
但说实话……我太懒了,没去实现。😅
场景 2 — 矩阵乘法
现在让我们来看看GPU最喜欢的东西。
矩阵乘法。
尽管名字听起来吓人,但原理很简单。想象两个数字网格。要计算结果矩阵中的一个单元格:
-
我们从第一个矩阵中取出一行。 -
第二个矩阵中的一列 -
成对乘数 -
将结果相加。
例子:
[1 2] [5 6]
[3 4] × [7 8]
计算左上角单元格:
1×5 + 2×7 = 19
对结果矩阵中的每个单元格都必须重复此操作。
对于大型矩阵,这很快就会变成数百万次的乘法运算。
这正是GPU设计之初就旨在处理的那种工作负载。
结果
结果非常明确。
WebGPU 完全碾压 JavaScript。
矩阵越大,这种差异就越大。
这完全合情合理:
矩阵乘法本质上是同一个简单操作重复数千次或数百万次——这正是 GPU 大显身手的场景。
别忘了,矩阵乘法是计算机科学中最重要的运算之一。矩阵乘法广泛应用于:
-
计算机图形 -
物理模拟 -
科学计算 -
当然还有……我们挚爱的法学硕士们🤖
场景 3 — 图像处理流程
第三个基准测试更接近于传统的图形工作:图像处理流程。
在这里,GPU 再次完全压制了CPU 的实现。
这种工作负载非常适合GPU:
-
每个像素都可以独立处理。 -
同样的操作可以应用于成千上万个像素。
这与 GPU 执行模型完美契合。
那么我们应该用 WebGPU 取代 JavaScript 吗?
当然不是。🙂
WebGPU 功能强大,但它只适用于某些类型的问题。一般来说,WebGPU 在以下情况下能发挥出色作用:
-
执行许多简单的操作 -
大量数据 - 并联
对于常规应用程序逻辑,JavaScript 仍然是完美的工具。
仍然存在一些实际限制
WebGPU 也是一项相对较新的技术。
如果你能控制环境,并且可以要求用户运行现代浏览器,那么你完全可以开始进行相关实验。
但是,如果你要为广大用户群体开发应用——比如有人可能会在 2018 年的某个奇怪的 Android 浏览器中打开你的应用——那你最好还是谨慎一些。
或者实现备用方案,例如使用 WebGL。
样板问题
如果你查看代码库,你会发现 WebGPU 需要相当多的设置。
你需要:
-
请求适配器 -
请求设备 -
创建缓冲区 -
配置管道 -
管理命令编码器 -
等等。
有很多重复的模板内容。
是的,像 Claude 或 ChatGPT 这样的编码代理可以提供帮助。
但这里有个小小的提醒⚠️
WebGPU 仍处于发展初期,LLM(语言逻辑模型)在生成正确的 WebGPU 代码方面并不总是表现出色。有时,您仍然需要回归传统的开发工作流程:
-
阅读文档 -
浏览 GitHub 问题 -
手动调试
就像以前一样。😄
最后想说的话
问题不再是WebGPU是否会变得重要。
真正的问题是,我们什么时候需要它。
因为 WebGPU 本质上是浏览器中使用 GPU 的一种新的、现代的标准。
对于GPU旨在解决的那类问题而言,它的性能极其强大。🚀
关注「索引目录」公众号,获取更多干货。

