SIMD acceleration for spatial interaction kernels - #590
Merged
Conversation
…ential) - Add float SLEEF macros to sleef_config.h (AVX2: 8 floats, NEON: 4 floats) - Add exp_kernel_float32() and normal_kernel_float32() to eidos_simd.h - Use SIMD kernels in FillSparseVectorForReceiverStrengths() - Add benchmark script for spatial interaction kernels
Modify FillSparseVectorForReceiverStrengths() to use the two-pass distance-then-transform path for most kernel types in 2D, enabling SIMD optimizations for Exponential and Normal kernels. The Fixed kernel retains the original single-pass special-case path since it doesn't benefit from SIMD (just assigns a constant). Benchmarks show 22% overall speedup at high neighbor counts (~2200), with Exponential and Normal kernels seeing 38-42% improvement.
Add SLEEF pow() function support (Sleef_powf8_u10avx2 for AVX2, Sleef_powf4_u10advsimd for NEON) and implement tdist_kernel_float32() to vectorize the Student's T distribution kernel calculation. The kernel computes: strength = fmax / pow(1 + (d/tau)^2 / nu, (nu+1)/2) Benchmarks show 62% speedup for Student's T kernel (130s -> 49s), contributing to 38% overall speedup for spatial interaction benchmarks.
Implement cauchy_kernel_float32() using AVX2/NEON intrinsics for the Cauchy kernel calculation: strength = fmax / (1 + (d/lambda)^2) Unlike exp/normal/tdist kernels, Cauchy uses only basic arithmetic operations (multiply, divide, add) so no SLEEF functions are needed. Benchmarks show 18% speedup vs original (40s -> 33s).
Implement linear_kernel_float32() using AVX2/NEON intrinsics for the Linear kernel calculation: strength = fmax * (1 - d / max_distance) Rewritten as: strength = fmax - d * (fmax / max_distance) Simple arithmetic (multiply + subtract) so gains are modest (~2%), but provides consistency with other SIMD-optimized kernels.
Remove sleef_benchmark_spatial_interaction.slim (only tested Gaussian/Exponential) and add benchmark_all_kernels.slim which tests all 6 kernel types: Fixed, Linear, Exponential, Normal, Cauchy, and Student's T.
Add documentation for benchmark_all_kernels.slim script including: - Entry in Contents section describing the 6 kernel types tested - Performance results table showing SIMD speedups on AVX2 - Usage instructions for running with SIMD vs scalar builds - Notes on adjusting neighbor density via W parameter 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Contributor
|
This looks good to me. Awesome performance improvements. You are knocking it out of the park! |
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.
Adds SIMD-optimized (AVX2/NEON) kernel functions for spatial interactions using SLEEF for transcendental functions. All kernel types except Fixed now use a two-pass approach (build distances, then batch transform) enabling vectorized strength calculations.
Summary Benchmark
50k individuals, ~2262 neighbors