阶段 4 · 计算基础18 分钟
第一个计算着色器:并行处理数组
@compute、dispatchWorkgroups 与全局调用 ID
把一组数字送入 GPU,每个 invocation 独立执行平方与偏移,再读回结果。
LEARNING GOALS
先明确本课目标
1
创建 ComputePipeline
2
调度工作组
3
用边界检查处理非整倍数元素
MENTAL MODEL · 再建立心智模型
dispatchWorkgroups 启动一个规则网格;每个 invocation 运行同一段 WGSL,但通过 global_invocation_id 处理不同元素。
MINIMAL EXAMPLE
一次 dispatch 到底启动多少个计算调用?
@workgroup_size 定义每个工作组包含的 invocation 数;dispatchWorkgroups 定义启动多少组。总调用规模是两者逐维相乘。
wgsl@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id: vec3u) {
if (id.x >= arrayLength(&output)) { return; }
output[id.x] = input[id.x] * 2.0;
}
// JavaScript:
// pass.dispatchWorkgroups(Math.ceil(count / 64));- 64 是组内大小 每个工作组沿 x 轴包含 64 个 invocation。
- dispatch 是组数 处理 count 个元素时要向上取整组数。
- 边界判断不可少 最后一组往往包含超出实际数组长度的 invocation。
每个合法 global_invocation_id.x 负责一个数组元素,所有元素可并行计算。
OPTIONAL · 按需查阅完整术语表与概念边界遇到陌生术语时再展开,不打断主线实验。
展开⌄
命令Compute Pass记录计算管线与 dispatchWorkgroups 的命令阶段。计算管线GPUComputePipeline将计算着色器入口和资源布局固化,供 Compute Pass 调度。资源绑定Storage Buffer可承载大型结构化数组的着色器资源,可只读或读写,常用于计算和 GPU 驱动数据。GPU 计算Workgroup计算 invocation 的局部协作组,大小由 @workgroup_size 定义,可共享 workgroup 内存。GPU 计算global_invocation_id计算着色器调用在整个 dispatch 网格中的全局坐标。GPU 计算dispatchWorkgroups指定各维工作组数量;总 invocation 数等于组数乘以 @workgroup_size。GPU 计算Compute Shader不经过光栅化、由 dispatchWorkgroups 启动的通用并行着色阶段,用 invocation 处理数据或图像。GPU 计算Data Parallelism让大量 invocation 对不同数据元素执行相同程序的并行模式,适合向量、图像和粒子处理。GPU 计算Invocation着色器入口函数的一次执行实例;许多 invocation 运行同一段代码,但通过内建 ID 处理不同顶点、片元或计算数据。GPU 计算workgroup_sizeWGSL 计算入口属性,用三个常量规定每个工作组在 x、y、z 方向包含多少个 invocation。
LIVE EXPERIMENT · 先获得反馈
边改边运行
浏览器加载后会激活代码编辑器、独立运行环境与实时输出。
本课挑战
实现向量归一化并处理零向量。
回到原理,解释刚才发生了什么
先用结果建立反馈,再按运行流程、核心原理和知识关系逐层深入。
CORE IDEA
核心讲解
并行而非自动加速
工作必须能拆成大量相似、相对独立的任务。数据搬运和调度也有成本,小数组未必比 CPU 快。
边界检查不可省
调度数量通常向上取整到工作组大小,因此最后一个工作组可能包含超出数据长度的 invocation。
OPTIONAL · 迁移时查阅WebGPU 与 WebGL2 对照主线实验完成后,再用完整映射处理跨平台或跨 API 迁移。
展开⌄
WebGL2 没有 Compute Pipeline;传统 GPGPU 必须借用顶点或片元阶段。
WebGL
把计算映射为全屏绘制、纹理输出或 Transform Feedback,并受图形管线形状约束。
WebGPU
ComputePipeline 直接调度工作组,不需要三角形、Framebuffer 或光栅化。
迁移计算时从数据并行维度重新设计 dispatch,不要保留为 GPGPU 凑出的全屏三角形。