Skip to content

Optimize AVX2 ggml_vec_dot_q4_0_q8_0: two FMA accumulator chains - #31

Open
codspeed-hq[bot] wants to merge 1 commit into
masterfrom
codspeed-optim-unroll-the-avx2-ggml-vec-dot-q4-0-q8-0-loop-into-t-1785229421638
Open

Optimize AVX2 ggml_vec_dot_q4_0_q8_0: two FMA accumulator chains#31
codspeed-hq[bot] wants to merge 1 commit into
masterfrom
codspeed-optim-unroll-the-avx2-ggml-vec-dot-q4-0-q8-0-loop-into-t-1785229421638

Conversation

@codspeed-hq

@codspeed-hq codspeed-hq Bot commented Jul 28, 2026

Copy link
Copy Markdown

Summary

Optimizes the AVX2 implementation of ggml_vec_dot_q4_0_q8_0 (ggml/src/ggml-cpu/arch/x86/quants.c), the per-row dot-product kernel used by every Q4_0 matrix multiplication. ggml_compute_forward_mul_mat calls it once per output element, so it dominates every Q4_0 linear/projection layer of transformer inference (prompt processing, decode and the LM head).

Analysis

On the CodSpeed micro suite, mul_mat[q4_0] (~102 ms in CPU simulation) spends essentially all of its time in this kernel. The AVX2 inner loop processed one 32-element block per iteration and accumulated every block into a single __m256 acc via _mm256_fmadd_ps. That forms a serial dependency chain — each block's FMA must wait for the previous block's FMA to retire — so the loop is FMA-latency bound, and the per-iteration loop-control work is paid on every block.

Change

Process two blocks per iteration into two independent accumulators (acc0, acc1), each with its own scale and nibble/maddubs chain, then combine them with a single _mm256_add_ps before the existing hsum_float_8 reduction. A trailing scalar-style loop handles an odd final block. The per-block computation (bytes_from_nibbles_32, the -8 offset, mul_sum_i8_pairs_float, the FMA) is byte-for-byte the same as before — only the accumulator that receives it changes. This keeps two FMA chains in flight to hide latency and halves the loop-control overhead. The change is confined to the #if defined(__AVX2__) branch; the AVX/SSSE3/scalar paths are untouched.

Correctness

The result is mathematically equivalent: the two accumulators sum the same per-block products, just partitioned across two lanes, and are added before the horizontal reduce — the same class of float-reassociation the kernel already performs across its 8 SIMD lanes.

Performance (CodSpeed, CPU simulation)

Measured locally through the CodSpeed CLI on the mul_mat micro benchmarks:

Benchmark Metric Base Head Change
mul_mat[q4_0] cpuTotal 0.101908 s 0.098354 s -3.5%
mul_mat[q4_0] instructions 0.093849 s 0.090295 s -3.8%
mul_mat[q4_0] cache 0.0047673 s 0.0047674 s identical
mul_mat[q4_0] memory 0.0032914 s 0.0032915 s identical

The cache and memory components are byte-for-byte identical — the win is a pure, deterministic instruction-count reduction. mul_mat[f32] and mul_mat[q4_k] are unchanged (no regressions). The kernel also feeds the walltime macro benchmarks' Q4_0 layers (prompt_layer[q4_0], decode_layer[q4_0]), which exercise the same hot path.

… chains

Process two Q4_0 blocks per iteration into two independent __m256
accumulators (acc0/acc1) instead of one, keeping two _mm256_fmadd_ps
chains in flight to hide FMA latency and halving loop-control overhead.
A trailing scalar-style loop handles an odd final block, and the two
partial sums are combined with a single _mm256_add_ps before the
existing hsum_float_8 reduction.

The per-block computation is unchanged; only the accumulator that
receives each block's product changes. The result is mathematically
equivalent (same float reassociation the kernel already performs across
its SIMD lanes). Only the __AVX2__ branch is touched.
@github-actions github-actions Bot added the ggml label Jul 28, 2026
@codspeed-hq

codspeed-hq Bot commented Jul 28, 2026

Copy link
Copy Markdown
Author

Merging this PR will not alter performance

✅ 28 untouched benchmarks


Comparing codspeed-optim-unroll-the-avx2-ggml-vec-dot-q4-0-q8-0-loop-into-t-1785229421638 (fa9c3be) with master (46819c9)

Open in CodSpeed

@codspeed-hq
codspeed-hq Bot marked this pull request as ready for review July 28, 2026 09:23
@codspeed-hq
codspeed-hq Bot requested a review from coco-speed July 28, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant