refactor(decimal): dispatch numeric kernels on one storage width - #9756
Conversation
Signed-off-by: Matt Katz <[email protected]>
Merging this PR will regress 1 benchmark
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | random_i8[0.5] |
67.2 µs | 91.3 µs | -26.37% |
| ⚡ | Simulation | random_i16[0.8] |
92.1 µs | 74.4 µs | +23.81% |
| ⚡ | Simulation | compact_sliced[(1024, 90)] |
1.5 µs | 1.3 µs | +16.67% |
| ⚡ | Simulation | compact_sliced[(2048, 90)] |
1.6 µs | 1.4 µs | +15.95% |
| ⚡ | WallTime | mul_u32_nonnull_avx512 |
6.3 µs | 5.6 µs | +11.72% |
| ⚡ | Simulation | allocate_drop_bytes[0] |
520.2 ns | 466 ns | +11.62% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing mk/decimal-kernel-monomorphization (8927d20) with develop (dab1684)
Footnotes
-
206 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. ↩
checked_decimal_arraysis generic over the working width (6 types) and the operator (4), so there are 24 copies of the outer function. Inside each copy, amatch_each_decimal_value_type!on the lhs storage type nests another on the rhs storage type, so every copy contains 36checked_lanesclosures. The 24 outer functions plus their 24 × 36= 864 closures make instantiations.The nesting exists because a
DecimalArray's storage width is independent of its precision, so two operands sharing aDecimalDTypemay still be stored at different widths.Instead, this PR dispatches on a single storage width. A mismatched pair is first widened to the wider of the two with the existing
widened_buffer(zero-copy when they already match), and the lane loop then runs once per (working width, operator, storage width) with the same inline checked cast as before.Mono items in
vortex-array(cargo +nightly rustc -p vortex-array --lib -- -Zprint-mono-items):checked_decimal_arraysnumeric::decimal::*module totallane_kernels::*totalMatched-storage inputs take the code path they did before, so the
binary_opsdecimal benchmarks are unchanged within noise.