概览WebGPU 为浏览器带来现代图形与通用计算能力。实战中需要重视设备能力检测(`adapter` 与 `device.limits`)、资源布局(Buffer/Texture)、着色器管线(Render/Compute)以及可重复的性能验证流程。能力检测与设备初始化async function init() {
if (!('gpu' in navigator)) throw new Error('WebGPU 未支持')
const adapter = await navigator.gpu.requestAdapter()
if (!adapter) throw new Error('未获取到适配器')
const device = await adapter.requestDevice()
const limits = device.limits
console.table({
maxBindGroups: limits.maxBindGroups,
maxComputeWorkgroupSizeX: limits.maxComputeWorkgroupSizeX,
maxComputeWorkgroupSizeY: limits.maxComputeWorkgroupSizeY,
maxComputeWorkgroupSizeZ: limits.maxComputeWorkgroupSizeZ,
})
return { device }
}
计算管线示例(WGSL)@group(0) @binding(0) var<storage, read> input: array<f32>
@group(0) @binding(1) var<storage, read_write> output: array<f32>
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) gid: vec3u) {
let i = gid.x;
if (i < arrayLength(&input)) {
output[i] = input[i] * 2.0;
}
}
提交与计时验证async function runCompute(device, inputData) {
const size = inputData.length * 4
const input = device.createBuffer({ size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST })
const output = device.createBuffer({ size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC })
device.queue.writeBuffer(input, 0, new Float32Array(inputData))
const module = device.createShaderModule({ code: wgslSource })
const pipeline = device.createComputePipeline({ compute: { module, entryPoint: 'main' } })
const bindGroup = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [
{ binding: 0, resource: { buffer: input } },
{ binding: 1, resource: { buffer: output } },
],
})
const encoder = device.createCommandEncoder()
const pass = encoder.beginComputePass()
pass.setPipeline(pipeline)
pass.setBindGroup(0, bindGroup)
const workgroups = Math.ceil(inputData.length / 64)
pass.dispatchWorkgroups(workgroups)
pass.end()
const t0 = performance.now()
device.queue.submit([encoder.finish()])
await device.queue.onSubmittedWorkDone()
const t1 = performance.now()
const readback = device.createBuffer({ size, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST })
const copyEncoder = device.createCommandEncoder()
copyEncoder.copyBufferToBuffer(output, 0, readback, 0, size)
device.queue.submit([copyEncoder.finish()])
await readback.mapAsync(GPUMapMode.READ)
const result = new Float32Array(readback.getMappedRange()).slice()
readback.unmap()
return { result, elapsedMs: t1 - t0 }
}
性能与正确性要点以 `device.limits` 校验工作组与资源规模,避免越界与退化。使用 `performance.now()` 与帧内统计结合,构建可重复的测量。对输出进行断言或采样验证,确保计算正确性与稳定性。参考资料WebGPU Spec: https://www.w3.org/TR/webgpu/MDN WebGPU 指南: https://developer.mozilla.org/docs/Web/API/WebGPU_API

发表评论 取消回复