SIMD Optimized N-Body Simulation
A C++ brute-force N-body simulation pushed to a ~400x speedup with compiler optimizations, OpenMP multithreading, and hand-tuned AVX2 SIMD intrinsics.
After the Barnes-Hut project, I wanted to see how far I could push the other end of the spectrum - the humble brute-force O(N²) simulation. The naive double loop looks simple, but at N=20,000 that's 400 million force calculations and 400 million square roots per frame. This project is about squeezing every last cycle out of that algorithm.
What it does
- Brute-force O(N²) N-body simulation with Euler integration
- Profiling-driven optimization pipeline: baseline, compiler flags, multithreading, then SIMD
- Custom in-simulation profiler exporting per-step metrics to CSV
- Real-time OpenGL rendering of thousands of particles
Performance journey
| Stage | N=20,000 time (s) | Speedup |
|---|---|---|
| Unoptimized baseline | 477.85 | 1x |
| Compiler optimizations (LTCG, O2, FastMath) | 51.04 | 9.4x |
| + OpenMP multithreading (16 threads) | 7.41 | 64.5x |
| + AVX2 SIMD intrinsics | 1.21 | ~395x |
The profiler identified the square root as the bottleneck - 29 clock cycles per call versus 1 for an add - so the SIMD kernel replaces it with the hardware-approximate _mm256_rsqrt_ps intrinsic and computes 8 interactions in parallel using mixed-precision arithmetic.
Tech highlights
- AVX2 256-bit intrinsics - 8 float interactions per instruction
- OpenMP
parallel forover the outer loop (16 threads) - LTCG / O2 / FastMath compiler optimizations
- Custom CSV profiler and real-time metrics display
The full report is available as a PDF: Read the report.
I've also written up the whole journey as a blog series - this is Part 2.