本项目不会将任何单一基准测试表视为普遍真理。WebGPU 性能在很大程度上取决于浏览器版本、驱动质量、GPU 架构、数组大小,以及你是否能在多次运行之间复用缓冲区。
使用交互式 Demo在你自己的机器上测试当前构建。比较以下指标:
- GPU 时间 - 仅计算工作
- 总时间 - 上传、计算和回读合计
- CPU 时间 -
TypedArray.sort()作为本地基准
小数组通常更倾向于 CPU,因为缓冲区传输开销占主导地位。更大的数组才是 GPU 排序发挥作用的场景。
当你复用同一个 GPUContext 并在多次运行之间保持缓冲区存活时,重复排序的性能会更好。
| 使用场景 | 更好的起点 | 原因 |
|---|---|---|
| 通用参考实现 | BitonicSorter |
结构可预测,推理更简单 |
大型 Uint32Array 工作负载 |
RadixSorter |
对整数密集型数据的浪费比较更少 |
| 小型或一次性数组 | CPU 排序 | 设置成本更低 |
- 从小数组开始并确认正确性。
- 增加数组大小,直到传输开销不再占主导地位。
- 比较 GPU 专用时间与总时间;两者都很重要。
- 重复相同的运行数次,以平滑着色器编译和预热效果。
- GPU 时间更快,总时间更慢 通常意味着着色器工作没问题,但传输/设置开销占主导地位。
- GPU 时间和总时间都更快 表明浏览器/GPU 非常适合该工作负载。
- Radix 比 Bitonic 慢 可能发生在较小的数组上,额外的趟次无法很好地摊销。
const gpu = new GPUContext();
await gpu.initialize();
const sorter = new BitonicSorter(gpu);
await sorter.sort(batchA);
await sorter.sort(batchB);const sorter = new RadixSorter(gpu);
sorter.preallocate(1_000_000);在开发时启用验证,当你只需要原始吞吐量测量时再禁用它。
仓库附带了一个专门为此目的维护的浏览器测试场。打开交互式 Demo,选择你的工作负载大小,并在目标机器上比较 Bitonic、Radix 和 CPU 的耗时。