Use Fn for out-of-place lane kernels - #9419
Conversation
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Merging this PR will regress 1 benchmark
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | compress_fsst[(1000, 64, 8)] |
1 ms | 1.2 ms | -11.08% |
| ⚡ | Simulation | copy_non_nullable[65536] |
1.7 ms | 1.2 ms | +39.85% |
| ⚡ | WallTime | words_gather_scalar[65536] |
9.4 µs | 8.2 µs | +13.6% |
| ⚡ | Simulation | take[small_m/shuffled/primitive/nonnull/chunks=1024/indices=256] |
2.3 ms | 2 ms | +13.27% |
| ⚡ | Simulation | take[small_m/shuffled/primitive/nonnull/chunks=1024/indices=1000] |
6.1 ms | 5.4 ms | +13.1% |
| ⚡ | Simulation | take[small_m/shuffled/primitive/nonnull/chunks=16384/indices=1000] |
10.2 ms | 9 ms | +12.82% |
| ⚡ | Simulation | take[core/shuffled/primitive/nonnull/chunks=1024/indices=10000] |
14.8 ms | 13.3 ms | +11.71% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ct/map-into-fn (e973d82) with develop (b363fb7)
Footnotes
-
89 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
|
Fn for out-of-place lane kernels
|
I guess we could be a bit more precise with which is |
Narrows the out-of-place lane-kernel callback bounds from
FnMuttoFnand propagates that contract through the currentvortex-arrayadapters, so callers cannot introduce loop-carried state into per-lane work.The decimal speedup comes from the callback shape after monomorphization. The old adapter reached the loop through
&mut &mut Closure, while theFnversion uses shared references and lets LLVM vectorize the range check.Fnis not required to recover this codegen: passing the stateless closure by value through the existingFnMutAPI also vectorizes, but this PR choosesFnbecause these kernels model independent per-lane work and do not need mutable callback state.Codegen investigation
cast_decimal_bufferpreviously passed&mut castintotry_map_into. That monomorphized the kernel withF = &mut Closure, then its chunk helper received&mut F, producing the nested mutable receiver.FnMutadapter&mut &mut Closure&&Closurei64values processed per iteration on arm64FnMutvariant&mut ClosureThe diagnostic variant kept every
FnMutbound and only moved the closure intotry_map_into. A narrower fix could make that call-site change, or otherwise restructure the helper to avoid the nested mutable receiver, without restricting the public callback bound.Local benchmark results
Compared
b363fb7(FnMut) withe973d82(Fn) on arm64 macOS using rustc 1.97.1,-C target-cpu=native, the bench profile, and CodSpeed's wall-time runner. Each run used 1,000 samples, and the order alternated across three baseline/candidate pairs.The
copy_non_nullablecase casts 65,536 non-nullable decimal values through the affected densetry_map_intopath.FnMutFnThe median run fell from 23.33 µs to 13.37 µs, a 42.7% reduction. Other changed arithmetic, comparison, and cast monomorphizations showed no consistent separation, while the unchanged Boolean and in-place cast controls were flat.
A separate three-pair check of the CodSpeed-reported
compress_fsst[(1000, 64, 8)]regression used 500 samples per run. Its median run was 112.4 µs for the baseline and 111.9 µs for this PR, so the local runs did not reproduce that regression.