// Experiment: keep the GPU frequency governor boosted by running a small // continuous compute load (one workgroup) from a separate device, to // quantify how much of the multi-dispatch backend's time is the 300 MHz // idle clock rather than the work. import { installNodeWebGpu, requestDevice } from './gpu.mjs'; async function main() { await installNodeWebGpu(); const { device } = await requestDevice(); const code = ` @group(0) @binding(0) var st: array; @compute @workgroup_size(64) fn main(@builtin(local_invocation_index) lid: u32) { var x: f32 = st[lid]; for (var i: u32 = 0u; i < 15000u; i = i + 1u) { x = x * 1.0000001 + 1e-8; } st[lid] = x; }`; const module = device.createShaderModule({ code }); const pipeline = device.createComputePipeline({ layout: 'auto', compute: { module, entryPoint: 'main' } }); const buf = device.createBuffer({ size: 256, usage: GPUBufferUsage.STORAGE }); const bg = device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [{ binding: 0, resource: { buffer: buf } }], }); const secs = Number(process.argv[2] ?? 30); const t0 = performance.now(); while (performance.now() - t0 < secs * 1000) { const enc = device.createCommandEncoder(); const pass = enc.beginComputePass(); pass.setPipeline(pipeline); pass.setBindGroup(0, bg); pass.dispatchWorkgroups(1); pass.end(); device.queue.submit([enc.finish()]); await device.queue.onSubmittedWorkDone(); } } main().then(() => process.exit(0)).catch((e) => { console.error(e); process.exit(1); });