This is an automated email from the ASF dual-hosted git repository.
apitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new dbbf7cf813 GH-49449: [C++] Backport xsimd neon fix (#49450)
dbbf7cf813 is described below
commit dbbf7cf8136da31b77f78f00a51d62992802c2c2
Author: Antoine Prouvost <[email protected]>
AuthorDate: Mon Mar 9 10:03:29 2026 +0100
GH-49449: [C++] Backport xsimd neon fix (#49450)
### Rationale for this change
Performance in hot code.
There is a bug in xsimd where the rshift/lshift for Neon are implemented
with a scalar loop instead of the appropriate SIMD intrinsics. This code path
is core to the `unpack` routine in Parquet reads.
https://github.com/xtensor-stack/xsimd/pull/1266
### What changes are included in this PR?
A bug backport.
### Are these changes tested?
Yes.
### Are there any user-facing changes?
No.
* GitHub Issue: #49449
Authored-by: AntoinePrv <[email protected]>
Signed-off-by: Antoine Pitrou <[email protected]>
---
cpp/src/arrow/util/bpacking_simd_kernel_internal.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/cpp/src/arrow/util/bpacking_simd_kernel_internal.h
b/cpp/src/arrow/util/bpacking_simd_kernel_internal.h
index f8cbe53292..70329dcb34 100644
--- a/cpp/src/arrow/util/bpacking_simd_kernel_internal.h
+++ b/cpp/src/arrow/util/bpacking_simd_kernel_internal.h
@@ -148,6 +148,10 @@ constexpr bool IsSse2 = std::is_base_of_v<xsimd::sse2,
Arch>;
template <typename Arch>
constexpr bool IsAvx2 = std::is_base_of_v<xsimd::avx2, Arch>;
+/// Whether we are compiling for the Neon or above in the arm64 family.
+template <typename Arch>
+constexpr bool IsNeon = std::is_base_of_v<xsimd::neon, Arch>;
+
/// Wrapper around ``xsimd::bitwise_lshift`` with optimizations for non
implemented sizes.
//
// We replace the variable left shift by a variable multiply with a power of
two.
@@ -196,6 +200,15 @@ auto left_shift(const xsimd::batch<Int, Arch>& batch,
return xsimd::bitwise_cast<Int>(shifted0 | shifted1);
}
+ // TODO(xsimd) bug fixed likely in xsimd>14.0.0
+ // https://github.com/xtensor-stack/xsimd/pull/1266
+ if constexpr (IsNeon<Arch>) {
+ using SInt = std::make_signed_t<Int>;
+ constexpr auto signed_shifts =
+ xsimd::batch_constant<SInt, Arch, static_cast<SInt>(kShifts)...>();
+ return xsimd::kernel::bitwise_lshift(batch, signed_shifts.as_batch(),
Arch{});
+ }
+
return batch << shifts;
}
@@ -252,6 +265,15 @@ auto right_shift_by_excess(const xsimd::batch<Int, Arch>&
batch,
return xsimd::bitwise_rshift<kMaxRShift>(left_shift(batch, kLShifts));
}
+ // TODO(xsimd) bug fixed likely in xsimd>14.0.0
+ // https://github.com/xtensor-stack/xsimd/pull/1266
+ if constexpr (IsNeon<Arch>) {
+ using SInt = std::make_signed_t<Int>;
+ constexpr auto signed_shifts =
+ xsimd::batch_constant<SInt, Arch, static_cast<SInt>(kShifts)...>();
+ return xsimd::kernel::bitwise_rshift(batch, signed_shifts.as_batch(),
Arch{});
+ }
+
return batch >> shifts;
}