NVIDIA WGSL kernel: port the Apple arithmetic wins without the code-size changes #7
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of #1. Fallback-engine work: matters while
engine-cudadoes not exist, and afterwards for any non-NVIDIA discrete card. Smaller expected gain than the other workstreams, 5 to 15%, and the only one where origin has already done most of the thinking.History
ea5e5e7) got 1.8x on Apple M5 with a bundle of changes to the u64 kernel:gf64_mul_addfolding the row sum into the 128-bit product before one reductionmul_wide/gf64_sqrassembling the 128-bit product from 32-bit-valued partials with no carry comparespermute64phase loop (the code-size changes; the commit says code size dominates on Apple's compiler)09323d3) found that bundle 37% slower on NVIDIA and split the kernels: Metal gets the PR 87 kernel, everything else gets the pre-87 unrolled kernel (mining_u64.wgsl).Nobody has reported measuring the arithmetic changes alone on the unrolled kernel. NVIDIA's compiler likes unrolled code and dislikes runtime lane counts, so the plausible reading is that the loop restructuring caused the regression and the arithmetic was a win hidden under it.
Plan
Each step is its own harness run on a 5090, parity checked, kept only if positive:
mul_wideandgf64_sqrfrommining_u64_apple.wgslintomining_u64.wgsl, everything else unchanged.gf64_mul_addfor the internal layer (int_layer64), which is 22 rounds x 12 multiplies plus a sum, the densest multiply site.ext_layer64and the internal row sum.RC_INITIAL[r][i]with loop-variable indices viaRUST_LOG=naga=debugSPIR-V dump andnvdisasmon the driver's cache; if it is private-memory arrays, unroll the round loops fully so constants become immediates.Where the code goes
This is the one workstream that edits an origin kernel file. Rule from #1: do it as a new kernel file,
crates/engine-gpu/src/kernels/mining_u64_nvidia.wgsl, selected inkernels/mod.rsby vendor id 0x10DE, leavingmining_u64.wgslas origin's for every other vendor. The selection arm is a few lines under// lair:. If origin later improvesmining_u64.wgsl, we re-run the comparison and drop ours if theirs wins.Measure
Harness, one 5090, fixed batch 16M, workers 1, pipelining off, so kernel changes are the only variable. Report per step.
Origin coupling
One new kernel file and one selection arm. The kernel duplicates ~500 lines of origin code, which is the acceptable cost of not maintaining a patch on their file.
Closing as superseded. Every arithmetic idea listed here (carry-free wide products, the row sum folded into the multiply-add, deferred-carry accumulation, constants as immediates) has been implemented and measured in the native CUDA engine instead, where it could be expressed exactly: #16, #17, #23 and #26 take the 4090 from 144 MH/s on the wgpu kernel to 716, and the 5090 from 283 to 1104 per card. On NVIDIA hosts the wgpu kernel is now only the fallback when no CUDA driver is present, and a 5 to 15% improvement to a path that runs at a quarter of the rate is not worth a 500-line duplicate of an origin file to maintain through merges.
If a non-NVIDIA card ever joins the fleet, the relevant question is what origin's kernel does on that vendor, not this port.