From db2097c19f46cf009f954c67af4036363b9fa2d9 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 2 Aug 2026 10:11:00 +1000 Subject: [PATCH] Record fleet benchmark results and the optimisation story Final ordering at 128^3/128ch now tracks GPU core count, which is the evidence the op is genuinely compute-bound rather than dispatch-bound: m3ultra (80c) 13.8ms | m2max (38c) 27.3ms | m1ultra (64c) 39.7ms | m1max (32c) 41.4ms m4pro reachable by ICMP but not ssh (key/user), and it is HANDS OFF per fleet rules, so it is excluded rather than provisioned. --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index 5c54b2e..8e6b511 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,41 @@ So the whole blocker is one operation: **submanifold 3×3×3 convolution**. - [ ] End-to-end inference - [ ] Fleet benchmark (m1max / m2max / m4pro / m1ultra / m3ultra) +## Fleet benchmark + +`SubMConv3d` at 128³ grid, 128 channels, ~10% occupancy (209,715 voxels) — the hot op +in the V-VAE. `conv_ms` is GPU work with a warm indice cache. + +| box | chip | GPU cores | conv_ms | Mvox/s | +|---|---|---|---|---| +| m3ultra | M3 Ultra | 80 | **13.8** | 15.25 | +| m2max | M2 Max | 38 | 27.3 | 7.69 | +| m1ultra | M1 Ultra | 64 | 39.7 | 5.28 | +| m1max | M1 Max | 32 | 41.4 | 5.06 | + +Getting there took two rounds, both of which the fleet data — not local profiling — +made visible: + +| version | m3ultra | note | +|---|---|---| +| per-offset loop | 81.6 ms | *slower than a 38-core M2 Max* | +| fused gather + matmul | 39.3 ms | 2.1× | +| cached device index | **13.8 ms** | 5.9× total | + +The first version was launch-latency bound: 2·K³ = 54 tiny dispatches per layer, none +large enough to occupy the GPU. The giveaway was throughput being *anti-correlated* with +core count — the 80-core Ultra lost to every smaller box, because its fused-die design +punishes small dispatches hardest. Fusing the taps into one `[N,K³·Cin]×[K³·Cin,Cout]` +matmul fixed the dispatch count; caching the prepared device index removed ~26 ms of +per-layer numpy bookkeeping that was hiding behind ~13 ms of real GPU work. + +Only after both did core count start predicting performance, which is the sign the op is +finally compute-bound. Note the M1 Ultra (64 cores) still barely beats the M1 Max (32) — +gather-heavy work scales poorly across UltraFusion. + +**Next target:** the indice map is now dominant (232–357 ms, CPU numpy) and is only +amortised because it is cached per coordinate set. It matters whenever coordinates change. + ## Correctness `spconv` cannot be installed here — that is the reason this port exists — so there is no