Repository navigation
Pack float32 comparison results into bitmap words - #10741
Conversation
Merging this PR will improve performance by 20.81%4 warnings, 1 note
Performance Changes
Tip Curious why performance improved? Comment Comparing Footnotes
|
|
This is part of #10675 |
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
9342120 to
bc683bb
Compare
## Summary - Tracking Issue: #9128 - Supersedes #10674 - Related discussion: #9694 - Independent float32 candidate: #10741 Attaches input validity directly to canonical RowFn output using the existing helper. Preserves kernel-output validation, relabeling, outer nullability, and the non-canonical mask fallback. `values.mask(valid)` builds and optimizes a `ScalarFnArray` to dispatch through parent-reduce rules. The benchmark-driven bypass stays inside RowFn to avoid adding canonical-specific dispatch to the generic builtin. It can be removed if `.mask()` gains equivalent direct dispatch. This revisits the abstraction concern in #9694. **Draft pending fresh isolated benchmarks on this head.** Saved results include regressions and do not establish a general speedup. <details> <summary>Saved benchmark evidence and validation</summary> The isolated validity snapshot `b1961452ea3505d4e2588e34b14c20ea177ed175` was compared with frozen `develop` at `a1693389301e446eec41373cb274d98a303d3ca0`. Measurements used Rust 1.99.1 / LLVM 23.1.1, 16 CGUs, no LTO, CPU 2, and 21 balanced paired blocks on Graviton3 C7g and Sapphire Rapids C7i. This was native wall time, not CodSpeed simulation. For nullable u64 addition with 64 rows and a right-hand constant, median paired time ratios were: | Target | Candidate / baseline time | 95% paired bootstrap interval | | --- | ---: | ---: | | NEON | 0.798 | 0.796–0.802 | | AVX2 | 0.850 | 0.846–0.852 | | AVX-512 | 0.846 | 0.844–0.855 | The isolated snapshot also had flagged regressions outside that case: roughly 3.4% slower ARM u64 multiply and up to 4.2% slower AVX2 byte comparisons. No regressions crossed the 3% flag on AVX-512 in that run. These movements remain part of the review, even where unchanged code is sensitive to compiler context or binary layout. A separate combined packing/validity candidate at `8d8ef8151454bbc73e1cd0b236567542a1401cbe`, based on `d834a11faa79370b4d2e0bbcc73195f451a8a212`, retained the small-batch gain but regressed nullable u64 add by about 12% at 8,192 rows and 18% at 32,768 rows on AVX2. Profiling found a byte-identical retry hot loop with essentially unchanged instructions per operation and more cycles. The precise placement-sensitive mechanism remains unresolved. That combined result does not isolate this PR. The combined candidate passed 225 RowFn tests and 232 binary-function tests on that newer base, including output validation, allocator, and deferred-error coverage. Separate native probes checked null-row arithmetic errors and comparison edge cases. The changed file passed the pinned formatter. These are saved checks, not fresh validation of this individual PR. This PR is rebased onto `c750fbd80882f78efd6a2703bc0f3e17f1aca9f9`. The patch is unchanged by the rebase. Tests and benchmarks were not rerun after it. </details> --------- Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Summary
Routes float32 comparisons through the existing word-packing collectors. This recovers the measured float32 gains from the RowFn comparison investigation with two private dispatch changes. It is independent of the comparison migration and fusion work in #10676 and #10675.
Changes
Adds
F32to the existing collector selections for array pairs and array/constant comparisons. Integer collector policies remain unchanged. The floating-point documentation now accounts for NaN signs and payloads.Draft pending fresh isolated benchmarks on this head. Saved measurements show a consistent float32 gain, but also some unrelated ARM regressions. The later combined packing/validity candidate had an AVX2 regression that has not been attributed to either change individually.
Saved benchmark evidence and validation
The isolated packing snapshot
4c98df49e379853f8e990d9764791b5330511771was compared with frozendevelopata1693389301e446eec41373cb274d98a303d3ca0. Measurements used Rust 1.99.1 / LLVM 23.1.1, 16 CGUs, no LTO, CPU 2, and 21 balanced paired blocks on Graviton3 C7g and Sapphire Rapids C7i. This was native wall time, not CodSpeed simulation.Across 48 float32 cases at 8,192 and 65,536 rows, covering array pairs, both constant orientations, equality/ordering, and four validity shapes, the median block ratios of equally weighted geometric means were:
Among all 375 probe cases, the isolated snapshot had no flagged regressions on AVX2 or AVX-512. ARM had four, including roughly 4.7% slower u64 multiply and 4.6% slower large f64 equality. Those paths do not use the changed float32 collector, so their movement is not evidence of extra float32 work, but it still counts against a no-regression claim.
A separate combined packing/validity candidate at
8d8ef8151454bbc73e1cd0b236567542a1401cbe, based ond834a11faa79370b4d2e0bbcc73195f451a8a212, retained the float32 gain but regressed large nullable u64 add by about 18% on AVX2. Profiling found a byte-identical retry hot loop with essentially unchanged instructions per operation and more cycles. The precise placement-sensitive mechanism remains unresolved. That combined result does not isolate this PR.The combined candidate passed 225 RowFn tests and 232 binary-function tests on that newer base. Separate native probes checked scalar-reference results and float/encoding/tail edge cases. The changed file passed the pinned formatter. These are saved checks, not fresh validation of this individual PR.
This PR is rebased onto
c750fbd80882f78efd6a2703bc0f3e17f1aca9f9. The patch is unchanged by the rebase. Tests and benchmarks were not rerun after it.