Use RowFn for primitive numeric comparisons - #9547
Conversation
Merging this PR will degrade performance by 7.19%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | or_chain[16] |
1.4 ms | 2.1 ms | -31.45% |
| ❌ | Simulation | or_chain[1024] |
1.5 ms | 2.1 ms | -31.13% |
| ❌ | Simulation | float_gt[16] |
292.3 µs | 383.4 µs | -23.78% |
| ❌ | Simulation | case_when_nary_10_conditions[1000] |
381.6 µs | 498.2 µs | -23.39% |
| ❌ | Simulation | float_gt[1024] |
322.7 µs | 416.5 µs | -22.53% |
| ❌ | Simulation | int_gt[16] |
113.4 µs | 146.1 µs | -22.37% |
| ❌ | Simulation | int_gt[1024] |
120.2 µs | 151.8 µs | -20.78% |
| ❌ | Simulation | lt_i64_nullable |
135.3 µs | 170.6 µs | -20.69% |
| ❌ | Simulation | or_chain[8192] |
2.7 ms | 3.3 ms | -18.17% |
| ❌ | Simulation | is_not_null_pred[16] |
232.5 µs | 282.3 µs | -17.62% |
| ❌ | Simulation | eq_i64_constant |
99.4 µs | 120.5 µs | -17.55% |
| ❌ | Simulation | is_not_null_pred[1024] |
249 µs | 300.6 µs | -17.16% |
| ❌ | Simulation | case_when_nary_early_dominant[1000] |
217.3 µs | 258.2 µs | -15.87% |
| ❌ | Simulation | case_when_nary_equality_lookup[1000] |
326.7 µs | 387.2 µs | -15.64% |
| ❌ | Simulation | case_when_nary_3_conditions[1000] |
221 µs | 260.4 µs | -15.1% |
| ❌ | Simulation | int_gt[8192] |
171.4 µs | 201.7 µs | -15.02% |
| ❌ | Simulation | compare_int_nullable |
207.5 µs | 243.8 µs | -14.91% |
| ❌ | Simulation | baseline_eq[4, 1024] |
98.1 µs | 115.3 µs | -14.88% |
| ❌ | Simulation | baseline_eq[16, 1024] |
99.5 µs | 116.7 µs | -14.74% |
| ❌ | Simulation | float_gt[8192] |
580.8 µs | 678 µs | -14.33% |
| ... | ... | ... | ... | ... | ... |
ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ct/row-fn-binary-numeric-comparison (e4d3617) with develop (332ae0b)2
Footnotes
-
54 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. ↩
-
No successful run was found on
ct/row-fn-associated-output(4aa169c) during the generation of this report, sodevelop(332ae0b) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
b6f9f10 to
85d4992
Compare
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
d6060ee to
e4d3617
Compare
Progress towards #9128
Supersedes #9346. Depends on #9548.
Moves primitive numeric comparisons onto the associated-output
RowKernelAPI. The implementation covers all 11 numeric physical types, all six operators, and array/array, array/constant, constant/array, and constant/constant inputs. Float equality remains bitwise and ordering matchestotal_cmp.On x86-64, runtime dispatch selects AVX2 or AVX-512 and writes comparison masks directly into packed Boolean storage. Other targets retain the columnar implementation.
CodSpeed reports a
-7.59%aggregate result with 34 regressions, 13 improvements, and 1,934 unchanged benchmarks. These are AVX2 simulation results, so the local AVX-512 results do not explain them away. In same-artifact comparisons against the retained columnar path, RowFn ranges from 7.75% faster to 12.27% slower with AVX2 and from 5.32% faster to 8.87% slower with AVX-512.Local AVX2 and AVX-512 wall-time results
These results compare the RowFn and retained columnar paths in the same candidate artifact. They isolate the implementations within this PR rather than comparing
developagainst the full stack.The benchmark processes 65,536 rows on a Ryzen 9 7950X pinned to CPU 20. Each entry is the median of five independent runs with 501 samples per run. AVX2 uses
-C target-feature=+avx2. AVX-512 uses-C target-cpu=native.f64GTE, array/arrayi64GTE, array/arrayi64GTE, nullable array/arrayi64GTE, array/constanti64GTE, constant/arrayu64GTE, array/arrayThe native assembly uses mask comparisons and direct
kmovstores without expanding results into Boolean lanes. The AVX2 loop uses YMM comparisons andvmovmskps, with constant broadcasts outside the inner loop. Neither loop contains calls.CodSpeed simulation results
The Performance Analysis job reports:
-7.59%Representative regressions include:
eq_i64_constantlt_i64_nullableor_chain[16]The simulation build selects the AVX2 implementation through the test harness's compile-time gating. There is no evidence that these regressions come from CodSpeed failing to simulate AVX-512. The separate AVX2, AVX-512, and NEON wall-time jobs complete successfully, but these benchmarks are new and therefore lack a base comparison in the aggregate report.
Verification
vortex-array --all-featuressuite: 3,479 passed, one skippedcargo clippy -p vortex-array --all-targets --all-features -- -D warningscargo test --doc -p vortex-array --all-features: 74 passed, 20 ignoredcargo doc -p vortex-array --all-features --no-depscargo +nightly fmt --all -- --check