Skip to content

[MOD-17916] Reduce native-FP16 SIMD lanes in FP32 - #1021

Open
dor-forer wants to merge 1 commit into
MOD-17845-simd-dispatch-hygienefrom
fp16-avx512fp16-accumulator
Open

[MOD-17916] Reduce native-FP16 SIMD lanes in FP32#1021
dor-forer wants to merge 1 commit into
MOD-17845-simd-dispatch-hygienefrom
fp16-avx512fp16-accumulator

Conversation

@dor-forer

@dor-forer dor-forer commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Current stack: #1018#1019#1021.

The hybrid no longer has the full-FP32 version’s FHM dependency: GCC 12 emits zero FMLAL
instructions even when compiled under +fp16fml. It can be restacked independently if desired.

Describe the changes in the pull request

The AVX512FP16, NEON and SVE float16 distance kernels keep their throughput-critical multiply/accumulate loops in native FP16. Before returning, each half-precision accumulator is widened separately and the horizontal reduction is completed in FP32. Inner product also performs 1.0f - dot in FP32.

This is deliberately a performance-oriented compromise. It removes FP16 overflow caused solely by combining otherwise-finite SIMD lanes, without paying to widen both operands before every multiply.

AVX512FP16 scenario fixed

For dimension 32 with values of 100:

  • Every per-lane product is 10,000 and remains finite in FP16.
  • The mathematical total is 320,000.
  • The old FP16 horizontal reduction overflowed past 65,504 and returned infinity.
  • This change widens the finite lanes first and returns the finite total.

The regression covers dimensions 32, 35, 40, 64 and 128. At dimension 128 the largest per-lane partial is 40,000, while the final result is 1,280,000.

Intentional limitation

This does not make native-half kernels identical to the scalar FP32 contract:

  • An individual FP16 product or squared difference can still overflow.
  • A per-lane FP16 accumulator can still overflow before the final reduction.
  • Native-half accumulation retains its existing approximation error.

A dimension-only blocker cannot remove those cases because safety also depends on component magnitude. The advanced randomized tests now compare against the scalar FP32 reference while retaining the existing 1% error budget, making the approximation explicit.

Performance

The hot loops retain their native instructions:

  • x86: one 32-lane vfmaddph per 32 elements; two vcvtph2psx conversions appear only after the loop.
  • NEON: fmla v*.8h remains in the loop; fcvtl / fcvtl2 are in the final reduction.
  • SVE/SVE2: svmla_f16 remains in the loop; widening and FP32 reduction happen once at the end.

This avoids the full-FP32 version’s four operand conversions and two FP32 FMAs per 32 x86 elements.

A same-runner A/B against the previous native-AVX512FP16 implementation shows that the FP32 final reduction is not free. Across 104 matched IP/L2 dimension and residual cases, the old/hybrid latency ratio was 0.9700× on average and 0.9678× at the median—equivalent to about 3.1% and 3.3% higher hybrid latency, respectively. Dimensions 32–100 were commonly 5–11% slower; IP was about 2–3% slower at dimensions 256 and 1024, while some L2 cases were worse. This is the performance comparison relevant to deciding whether the additional final-reduction protection is worth keeping.

Old-vs-hybrid benchmark: https://github.com/RedisAI/VectorSimilarity/actions/runs/32647246414

The FP16-only benchmark matrix ran on an Intel Xeon Platinum 8488C with AVX512FP16. Across all 104 matched IP/L2 dimensions and residual specializations, this hybrid was 2.15× faster on average and 2.29× faster at the median than the existing AVX512F FP16-input kernel, which widens operands and accumulates in FP32.

Dimension Hybrid L2 AVX512F L2 Speedup Hybrid IP AVX512F IP Speedup
32 2.64 ns 3.45 ns 1.31× 2.63 ns 3.18 ns 1.21×
100 4.03 ns 8.71 ns 2.16× 3.82 ns 8.07 ns 2.11×
256 6.82 ns 17.0 ns 2.49× 6.56 ns 15.7 ns 2.39×
1024 32.0 ns 63.5 ns 1.98× 32.6 ns 55.7 ns 1.71×

The exceptions are also visible in the full matrix: both dimension-115 cases were about 8–10% slower, and a few 513–516 residual cases were near parity. The 10th-to-90th-percentile speedup was 1.21×–2.57×.

The same targeted workflow executed NEON, SVE and SVE2 on a Graviton4/Neoverse-V2 runner. The benchmark steps completed successfully; the workflow was intentionally cancelled only during the unrelated results-export step after logs were captured and both EC2 runners were stopped.

Benchmark: https://github.com/RedisAI/VectorSimilarity/actions/runs/32644106830

Which issue this PR fixes

  1. MOD-17916

Related issue

Files modified

  1. src/VecSim/spaces/L2/L2_AVX512FP16_VL_FP16.h
  2. src/VecSim/spaces/IP/IP_AVX512FP16_VL_FP16.h
  3. src/VecSim/spaces/L2/L2_NEON_FP16.h
  4. src/VecSim/spaces/IP/IP_NEON_FP16.h
  5. src/VecSim/spaces/L2/L2_SVE_FP16.h
  6. src/VecSim/spaces/IP/IP_SVE_FP16.h
  7. tests/unit/test_spaces.cpp

Verification

  • GCC 13 x86 release build: clean.
  • Local test_spaces: 1585/1585 passed.
  • Sapphire Rapids/AVX512FP16 coverage jobs: 2993/2993 and 2747/2747 passed; the new regression executed through the native public chooser.
  • Graviton4/SVE2: 2704/2704 passed; the new regression executed through the production chooser.
  • AVX512FP16 disassembly: native vfmaddph / vsubph hot loops; no FP16 horizontal add; widening occurs after the loop.
  • Clang 18 AArch64 compile at armv8.2-a+sve+fp16, -Wall -Wextra -Werror: clean, with no FMLAL.
  • GCC 12 AArch64 compilation under +fp16fml: zero FMLAL instructions.

ARM run: https://github.com/RedisAI/VectorSimilarity/actions/runs/32642761606

Mark if applicable

  • This PR introduces API changes
  • This PR introduces serialization changes

@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.19%. Comparing base (ee83c94) to head (930bc73).

Additional details and impacted files
@@                       Coverage Diff                        @@
##           MOD-17845-simd-dispatch-hygiene    #1021   +/-   ##
================================================================
  Coverage                            97.19%   97.19%           
================================================================
  Files                                  141      141           
  Lines                                 8435     8441    +6     
================================================================
+ Hits                                  8198     8204    +6     
  Misses                                 237      237           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dor-forer
dor-forer force-pushed the fp16-avx512fp16-accumulator branch from 4788e5d to bd65260 Compare August 20, 2026 14:47
@dor-forer
dor-forer changed the base branch from main to MOD-17845-simd-dispatch-hygiene August 20, 2026 14:47
@dor-forer
dor-forer force-pushed the fp16-avx512fp16-accumulator branch from bd65260 to 04aa990 Compare August 23, 2026 07:44
@dor-forer
dor-forer force-pushed the fp16-avx512fp16-accumulator branch from 04aa990 to 37c7c04 Compare August 23, 2026 07:48
@dor-forer dor-forer changed the title [MOD-16688] Accumulate the AVX512FP16 float16 kernels in fp32 [MOD-17916] Accumulate float16 SIMD kernels in fp32 Aug 23, 2026
@dor-forer
dor-forer requested a review from GuyAv46 August 23, 2026 08:36
@dor-forer
dor-forer force-pushed the fp16-avx512fp16-accumulator branch from 37c7c04 to fd9ebd9 Compare August 23, 2026 13:32
@dor-forer dor-forer changed the title [MOD-17916] Accumulate float16 SIMD kernels in fp32 [MOD-17916] Reduce native-FP16 SIMD lanes in fp32 Aug 23, 2026
@dor-forer
dor-forer force-pushed the fp16-avx512fp16-accumulator branch from fd9ebd9 to 930bc73 Compare August 23, 2026 13:52
@dor-forer dor-forer changed the title [MOD-17916] Reduce native-FP16 SIMD lanes in fp32 [MOD-17916] Reduce native-FP16 SIMD lanes in FP32 Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant