2.8 KiB
Optimization: SoA (float version)
- Author: Linus
- Predecessor: variant_float_inlining.cpp
- File(s): variants/variant_float_inlining_SoA.cpp
- Status: TBD
What this changes
Same SoA layout switch as the double variant_inlining_7_SoA, but starting
from the float baseline instead of the double one. Pedestrian struct is
replaced by file-scope vector<float> arrays (pos_x, pos_y, sb_e_x,
sb_e_y, sb_sq, e_x, e_y, w_x, w_y, curr_vel_x, curr_vel_y,
desired_v0, v_max, destination_x, destination_y, color). Board
obstacles stay AoS.
Mostly a setup step for the float AVX2 variant. Same reasoning as the double SoA: gets the j-side loads contiguous so the upcoming 8-wide AVX2 loop has clean aligned chunks.
The j loop also keeps the r_ab_norm > EPS ? : EPS and two_b_sq > EPS_SQ ? : EPS_SQ clamps from the float baseline. Float precision around close
encounters can collapse those to zero where double would not, and the clamp
keeps the division finite.
Code (relevant snippet)
See variants/variant_float_inlining_SoA.cpp.
Benchmark
Conditions: min of N runs (TBD), N_ITER=1000, -O3 -march=native -flto.
Diff is vs variant_float_inlining.
x86
Machine: TBD
Frequency: TBD
| N | W(n) [Flops] | T(n) [Cycles] | Performance [Flops/Cycle] | Diff vs Predecessor |
|---|---|---|---|---|
| 50 | ||||
| 100 | ||||
| 200 | ||||
| 500 |
ARM (Apple)
Machine: TBD
Frequency: TBD
| N | W(n) [Flops] | T(n) [Cycles] | Performance [Flops/Cycle] | Diff vs Predecessor |
|---|---|---|---|---|
| 50 | ||||
| 100 | ||||
| 200 | ||||
| 500 |
Analysis
Layout change only, so the expectation is roughly no win on its own. The
float scalar loop already auto-vectorises in pieces with -O3 -march=native, so SoA doesnt buy much over what the AoS version was
already doing. The real payoff lands in the AVX2 child.
Verify passes against baseline_float_n60_i500.csv (from
variant_float_baseline) at the 1cm tolerance.
Takeaway
Setup step for the AVX2 variant.