You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The row-major A/B added in #414's benchmark (RowMajorVnniBenchmarks) compares all three tiers ComputeRows dispatches between. On an AVX-512 host (AVX-512F+CD+BW+DQ+VL+VBMI, .NET 10.0.10, BDN 0.14.0, 3 warmup / 10 iterations, single-threaded), baseline is the AVX-512 maddubs kernel that #399's VNNI kernel displaced:
But plain AVX2 beats both, by 1.21x over VNNI at K=4096 and 1.21x at K=512. And ComputeRows (src/DotLLM.Cpu/Kernels/MatMul.cs:130) tiers Avx512BW && AvxVnni -> Avx512BW -> Avx2, so on this hardware the fastest of the three is the one tier that never gets selected.
This is the same shape as the #414 result on the R4 kernel, where the 256-bit AVX2 kernel beat the VNNI one by 1.8-1.9x. Two independent kernel families, same ordering: the 512-bit dual-block variants lose to 256-bit single-block. Consistent with the mechanism — Q8_0's per-block fp16 scale forces a convert-scale-FMA every 32 elements, and the Vector256->Vector512 assembly plus scale broadcast-and-insert costs more than the wider FMA saves.
Why this is not simply "flip the dispatch order"
ComputeRows is the decode path (GEMV, n == 1), and decode is memory-bandwidth-bound, not kernel-throughput-bound. A 1.21x microkernel win may not survive end-to-end at all. Measured earlier in the same investigation: decode on Llama-3.2-1B Q8_0 runs well under this machine's memory ceiling, so the kernel may not be the limiter.
So the microbenchmark justifies investigating, not changing. The change needs an end-to-end decode measurement before it is defensible.
Proposed work
Measure end-to-end decode tok/s with the dispatch preferring AVX2, against main, on Llama-3.2-1B Q8_0 — the number that decides this.
If it moves: reorder the tiers, with a comment recording the measurement, and keep the wider kernels reachable for hardware that orders them differently.
If it does not move: document that the tier ordering is performance-neutral for decode and close. That result is worth having written down, because it tells us decode work belongs in traffic reduction rather than kernel width.
Observation
The row-major A/B added in #414's benchmark (
RowMajorVnniBenchmarks) compares all three tiersComputeRowsdispatches between. On an AVX-512 host (AVX-512F+CD+BW+DQ+VL+VBMI, .NET 10.0.10, BDN 0.14.0, 3 warmup / 10 iterations, single-threaded), baseline is the AVX-512 maddubs kernel that #399's VNNI kernel displaced:VecDotQ8_0Avx512_4Rows(maddubs, pre-#399)VecDotQ8_0Vnni_4Rows(#399, currently shipped)VecDotQ8_0Avx2_4Rows(AVX2 maddubs)Two things follow:
ComputeRows(src/DotLLM.Cpu/Kernels/MatMul.cs:130) tiersAvx512BW && AvxVnni->Avx512BW->Avx2, so on this hardware the fastest of the three is the one tier that never gets selected.This is the same shape as the #414 result on the R4 kernel, where the 256-bit AVX2 kernel beat the VNNI one by 1.8-1.9x. Two independent kernel families, same ordering: the 512-bit dual-block variants lose to 256-bit single-block. Consistent with the mechanism — Q8_0's per-block fp16 scale forces a convert-scale-FMA every 32 elements, and the
Vector256->Vector512assembly plus scale broadcast-and-insert costs more than the wider FMA saves.Why this is not simply "flip the dispatch order"
ComputeRowsis the decode path (GEMV,n == 1), and decode is memory-bandwidth-bound, not kernel-throughput-bound. A 1.21x microkernel win may not survive end-to-end at all. Measured earlier in the same investigation: decode on Llama-3.2-1B Q8_0 runs well under this machine's memory ceiling, so the kernel may not be the limiter.So the microbenchmark justifies investigating, not changing. The change needs an end-to-end decode measurement before it is defensible.
Proposed work
main, on Llama-3.2-1B Q8_0 — the number that decides this.RowMajorVnniBenchmarkson a second microarchitecture before concluding anything general. One CPU is one CPU — @jamesburton's perf(cpu/matmul): AVX-512 VNNI for Q8_0 outer-product (AvxVnni.V512 / VPDPBUSD-512) — requires .NET 11 bump #322 numbers are Zen5 and ordered these differently.Acceptance criteria
References
src/DotLLM.Cpu/Kernels/MatMul.cs—ComputeRows(:130) and the three 4-row kernels (:696, :875, :975)benchmarks/DotLLM.Benchmarks/R4VnniBenchmarks.cs—RowMajorVnniBenchmarks