Optimize quantized and float32 distance kernels - #99
Merged
Conversation
- Shorten accumulation chains in AVX2 and AVX-512 extra-code kernels. - Optimize AVX2 binary dot products, including the HNSW search path. - Add shared float32 L2, dot, IP, and norm kernels with runtime SIMD dispatch, masked tails, and scalar fallbacks without Eigen. - Preserve distance conventions, packed layouts, and non-float templates. - Add kernel regression tests and IVF coverage at dimensions 420 and 960.
…ions # Conflicts: # src/simd/dispatch.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem and change
Several distance kernels serialize accumulation through one dependency chain, and raw float32 distances rely on Eigen instead of the library's runtime SIMD dispatch. This change introduces independent accumulators and shared handwritten float32 kernels while preserving distance conventions and packed-code layouts.
1 - dot), and squared norm through generic/AVX2/AVX-512 dispatch. Share four-accumulator SIMD implementations, with masked tails for unpadded and unaligned inputs. Generic float32 kernels use scalar loops with double accumulation; non-float templates retain Eigen.Validation
Checked the merged branch at
2377a92with native optimization disabled:cmake --build /tmp/rapdx-kernel-tests -j 4: passed.ctest --test-dir /tmp/rapdx-kernel-tests --output-on-failure -j 4: 78 passed, including explicit AVX2 and AVX-512 backend coverage.python -m pytest tests/python -q: 118 passed.Earlier local production-kernel benchmarks used a Xeon Gold 6418H, one thread pinned to CPU 0, GCC 14.3 (also Clang 15 for binary-dot/float studies),
-O3 -DNDEBUG, explicit ISA flags, and repeated alternating baseline/candidate timings. Ratios below are baseline time / candidate time for cached, aligned inputs:These are prior local microbenchmarks, not measurements rerun after the merge or a universal whole-index speedup claim. Host load/frequency was uncontrolled; performance depends on dimensions, cache behavior, compiler, and CPU. Benchmark artifacts remain outside this branch in the local
kernel-studyworkspace.Compatibility
No existing public API signatures, index formats, packed-code layouts, ISA requirements, or production dependencies change. Runtime dispatch retains a generic float32 fallback. Floating-point reassociation/FMA can change rounding and near-tie ordering; reference tests use numerical tolerances rather than bitwise equality.