Fluid Solver Optimization
CPU, OpenMP, CUDA
Reduced runtime 30.85s → 3.69s (8.36×) on CPU; best OpenMP ~10.77× at ~16-24 threads; CUDA kernels reached ~90.16 GiB/s.
Optimized a 3D Stable Fluids solver: (1) CPU locality + ILP (loop reordering, tiling, division to mult), (2) shared-memory parallelism with OpenMP (collapse, reductions, static scheduling; Red/Black Gauss-Seidel), (3) GPU acceleration with CUDA (persistent device memory, kernelized solver steps, Nsight-guided tuning). Profiled bottlenecks and scalability with perf/gprof and Nsight.
Highlights
- CPU: 30.85s → 3.69s (8.36×) via loop reordering + cache tiling + compiler/ILP optimizations.
- OpenMP: peak performance around 16-24 threads (~1.38s, ~10.77×); analyzed plateau from contention/sync effects.
- CUDA: lin_solve kernel dominated (~89.6%); achieved ~90.16 GiB/s and minimized transfer overhead with persistent device allocations.
What I did
- Identified hotspots with gprof/perf (lin_solve as primary target) and set up repeatable benchmarks across grid sizes.
- Implemented CPU-side locality/ILP improvements (loop order, tiling, hoisted reciprocals) and validated speedups.
- Parallelized solver loops with OpenMP (parallel for + collapse; reductions for convergence metrics) and evaluated strong scaling.
- Implemented CUDA kernels for solver steps (including Red/Black Gauss-Seidel updates) and tuned block geometry for coalescing (e.g., 32×4×1).
- Used Nsight Systems/Compute to attribute time, verify memory behavior, and document trade-offs (kernel launch + sync constraints).
Stack
- C/C++
- OpenMP
- CUDA
- Linux
- perf
- gprof
- Nsight Systems
- Nsight Compute