Compare primitive values with RowFn - #9587
Conversation
Merging this PR will regress 24 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | WallTime | lt_i64_nullable_avx512 |
2.9 µs | 4.4 µs | -35.26% |
| ❌ | WallTime | lt_i64_nullable_avx2 |
3 µs | 4.4 µs | -32.55% |
| ❌ | WallTime | lt_i64_nullable_neon |
3.5 µs | 4.9 µs | -29.37% |
| ❌ | WallTime | compare_int_nullable_avx512 |
3.6 µs | 5 µs | -28.24% |
| ❌ | WallTime | mul_u64_nonnull_neon |
15.2 µs | 20.7 µs | -26.72% |
| ❌ | WallTime | compare_int_nullable_avx2 |
3.9 µs | 5.1 µs | -22.21% |
| ❌ | WallTime | compare_int_nullable_neon |
5 µs | 6.2 µs | -19.72% |
| ❌ | WallTime | eq_i64_constant_avx512 |
2.1 µs | 2.6 µs | -17.39% |
| ❌ | Simulation | int_gt[16] |
97.3 µs | 116.8 µs | -16.68% |
| ❌ | Simulation | or_chain[16] |
1.1 ms | 1.4 ms | -16.08% |
| ❌ | Simulation | int_gt[1024] |
103.2 µs | 121.8 µs | -15.33% |
| ❌ | Simulation | or_chain[1024] |
1.2 ms | 1.4 ms | -15.12% |
| ❌ | WallTime | mul_i64_nonnull_neon |
17.1 µs | 20 µs | -14.6% |
| ❌ | WallTime | multiply_shapes_neon[(16384, PerRowPerRow)] |
17.2 µs | 20.1 µs | -14.57% |
| ❌ | Simulation | float_gt[16] |
237.3 µs | 277.7 µs | -14.54% |
| ❌ | Simulation | float_gt[1024] |
262.3 µs | 303.3 µs | -13.53% |
| ❌ | Simulation | is_not_null_pred[1024] |
203.7 µs | 234.9 µs | -13.27% |
| ❌ | Simulation | is_not_null_pred[16] |
195 µs | 224.4 µs | -13.09% |
| ❌ | Simulation | cold_misaligned[(16, 64)] |
345.6 µs | 391.4 µs | -11.7% |
| ❌ | Simulation | case_when_all_true[1000] |
102.4 µs | 115.4 µs | -11.32% |
| ... | ... | ... | ... | ... | ... |
ℹ️ 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/primitive-comparison-simd (139c28f) with develop (ba90f3d)3
Footnotes
-
106 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. ↩
-
4 benchmarks were run, but are now archived. If they were deleted in another branch, consider rebasing to remove them from the report. Instead if they were added back, click here to restore them. ↩
-
No successful run was found on
ct/row-fn-constant-decode(f21a243) during the generation of this report, sodevelop(ba90f3d) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
3e39406 to
931772a
Compare
931772a to
c0148bd
Compare
## Summary The measurement half of #9587, split out so the numbers land before the kernels do. Bottom of a three-PR stack: this PR, then #9599, then #9587. Tagging these with `#[cpu_features]` first means the walltime legs record the portable lane kernel's throughput on `avx2`, `avx512`, and `neon` metal as a baseline series. The kernel PR then reports against it rather than introducing both the benchmark and the thing it measures in one diff. ## Changes - Adds the primitive comparison cases a hand-written SIMD kernel would have to beat: constant on the left, `u8`, `u64`, and `f32`. - Tags those four with `#[cpu_features]`, so each walltime leg measures them under its own build flags instead of in simulation. The existing cases are untouched and keep their simulation series. - `bench_compare` now carries an `ItemsCount`, so the report reads as throughput rather than a time that only means something next to another run over the same array length. - Adds module docs recording why these four are tagged and the rest are not. Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
c0148bd to
46ad4bb
Compare
…9599) ## Summary Sweeps `#[cpu_features]` across the microbenchmarks that clearly earn it: the binary numeric arithmetic and comparison kernels. Those are portable lane loops — the source is identical on every target and the vector width the compiler picks comes from the build flags — which is the case the attribute exists for. Measuring them in simulation under one fixed `+avx2` build hides the only variable that matters. Middle of a three-PR stack: #9598, then this PR, then #9587. It carries no kernel changes of its own — everything here is a benchmark attribute — so it can be reordered or rebased onto `develop` without touching the other two. ## Changes Tagged: - `binary_ops`: the primitive arithmetic cases (`add_*`, `subtract_*`, `multiply_*`, `mul_*`, `div_i64_*`, `sub_i64_constant`, and the three `*_shapes` matrices) and the two primitive comparison cases (`eq_i64_constant`, `lt_i64_nullable`). - `compare`: `compare_int`, `compare_int_nullable`, `compare_int_constant`, `compare_int_eq`, `compare_float`. - `scalar_subtract`. - `lane_kernels`: `lanezip_checked_add_u32` and its `arrow_checked_add_u32` baseline. The baseline is tagged too — comparing the two is only meaningful under the same build flags. Left in simulation, with the reasoning recorded in each file's module docs: - Decimal arithmetic and comparison: `i128` widening and per-lane rescaling, not something a wider vector register decides. - Boolean `and`/`or`: already word-at-a-time over a bitmap. - String and struct comparison: dominated by view chasing and per-field dispatch. - Casts in `lane_kernels`: vectorization-sensitive, but out of scope here. Also left alone: the `between` benchmarks in `vortex-fastlanes` (`new_raw_prim_test_between` is a raw-primitive comparison kernel and does qualify) and the bit-packed comparison matrices. Both are `types =`/`consts =` parameterized, which `#[cpu_features]` has no coverage for yet, and both would fan out to dozens of walltime series. Worth a follow-up rather than a guess in this PR. Note that tagging moves a benchmark out of the sharded simulation job, so these series restart on the walltime legs instead of continuing their simulation history. Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
1163162 to
4edd7e4
Compare
72e2bc8 to
ebda2b0
Compare
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
ebda2b0 to
139c28f
Compare
Summary
Moves primitive comparisons entirely onto
RowFnto measure the limits of the generic path. This removes the handwritten SIMD and primitive-specific fallback.Changes
PrimitiveComparedeclaresINFALLIBLE = trueand routes every primitive type, comparison operator, and constant orientation through multiversionedRowVisitor::visit_bool. Cross-generated optimized x86-64 IR and assembly show that LLVM vectorizes the row comparisons, but this does not establish end-to-end benchmark parity. CodSpeed results for this PR cover the accumulated stack, including #9680 direct constant decoding.