-
Notifications
You must be signed in to change notification settings - Fork 4.3k
GH-51476: [C++][Parquet] Vectorise FindMinMax explicitly #51478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| // Licensed to the Apache Software Foundation (ASF) under one | ||
| // or more contributor license agreements. See the NOTICE file | ||
| // distributed with this work for additional information | ||
| // regarding copyright ownership. The ASF licenses this file | ||
| // to you under the Apache License, Version 2.0 (the | ||
| // "License"); you may not use this file except in compliance | ||
| // with the License. You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, | ||
| // software distributed under the License is distributed on an | ||
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| // KIND, either express or implied. See the License for the | ||
| // specific language governing permissions and limitations | ||
| // under the License. | ||
|
|
||
| #if defined(ARROW_HAVE_NEON) | ||
| # define FIND_MIN_MAX_PLATFORM FindMinMaxNeon | ||
| # define ARCH_PLATFORM xsimd::neon64 | ||
| #elif defined(ARROW_HAVE_SSE4_2) || defined(ARROW_HAVE_RUNTIME_SSE4_2) | ||
| # define FIND_MIN_MAX_PLATFORM FindMinMaxSse42 | ||
| # define ARCH_PLATFORM xsimd::sse4_2 | ||
| #endif | ||
|
|
||
| #if defined(FIND_MIN_MAX_PLATFORM) | ||
|
|
||
| # include "parquet/level_comparison_simd_internal.h" | ||
| # include "parquet/level_comparison_simd_kernel_internal.h" | ||
|
|
||
| namespace parquet::internal { | ||
|
|
||
| MinMax FIND_MIN_MAX_PLATFORM(const int16_t* levels, int64_t num_levels) { | ||
| return FindMinMaxSimd<ARCH_PLATFORM>(levels, num_levels); | ||
| } | ||
|
|
||
| } // namespace parquet::internal | ||
|
|
||
| # undef ARCH_PLATFORM | ||
| # undef FIND_MIN_MAX_PLATFORM | ||
| #endif // FIND_MIN_MAX_PLATFORM |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // Licensed to the Apache Software Foundation (ASF) under one | ||
| // or more contributor license agreements. See the NOTICE file | ||
| // distributed with this work for additional information | ||
| // regarding copyright ownership. The ASF licenses this file | ||
| // to you under the Apache License, Version 2.0 (the | ||
| // "License"); you may not use this file except in compliance | ||
| // with the License. You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, | ||
| // software distributed under the License is distributed on an | ||
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| // KIND, either express or implied. See the License for the | ||
| // specific language governing permissions and limitations | ||
| // under the License. | ||
|
|
||
| #if defined(ARROW_HAVE_RUNTIME_AVX2) | ||
| # define FIND_MIN_MAX_PLATFORM FindMinMaxAvx2 | ||
| # define ARCH_PLATFORM xsimd::avx2 | ||
| #endif | ||
|
|
||
| #if !defined(FIND_MIN_MAX_PLATFORM) | ||
| # error "This file must be compiled with a known SIMD micro architecture" | ||
| #endif | ||
|
|
||
| #include "parquet/level_comparison_simd_internal.h" | ||
| #include "parquet/level_comparison_simd_kernel_internal.h" | ||
|
|
||
| namespace parquet::internal { | ||
|
|
||
| MinMax FIND_MIN_MAX_PLATFORM(const int16_t* levels, int64_t num_levels) { | ||
| return FindMinMaxSimd<ARCH_PLATFORM>(levels, num_levels); | ||
| } | ||
|
|
||
| } // namespace parquet::internal | ||
|
|
||
| #undef ARCH_PLATFORM | ||
| #undef FIND_MIN_MAX_PLATFORM |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // Licensed to the Apache Software Foundation (ASF) under one | ||
| // or more contributor license agreements. See the NOTICE file | ||
| // distributed with this work for additional information | ||
| // regarding copyright ownership. The ASF licenses this file | ||
| // to you under the Apache License, Version 2.0 (the | ||
| // "License"); you may not use this file except in compliance | ||
| // with the License. You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, | ||
| // software distributed under the License is distributed on an | ||
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| // KIND, either express or implied. See the License for the | ||
| // specific language governing permissions and limitations | ||
| // under the License. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cstdint> | ||
|
|
||
| #include "parquet/level_comparison.h" | ||
|
|
||
| namespace parquet::internal { | ||
|
|
||
| #if defined(ARROW_HAVE_NEON) | ||
| MinMax FindMinMaxNeon(const int16_t* levels, int64_t num_levels); | ||
| #endif | ||
|
|
||
| #if defined(ARROW_HAVE_SSE4_2) || defined(ARROW_HAVE_RUNTIME_SSE4_2) | ||
| MinMax FindMinMaxSse42(const int16_t* levels, int64_t num_levels); | ||
| #endif | ||
|
|
||
| #if defined(ARROW_HAVE_RUNTIME_AVX2) | ||
| MinMax FindMinMaxAvx2(const int16_t* levels, int64_t num_levels); | ||
| #endif | ||
|
|
||
| } // namespace parquet::internal |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| // Licensed to the Apache Software Foundation (ASF) under one | ||
| // or more contributor license agreements. See the NOTICE file | ||
| // distributed with this work for additional information | ||
| // regarding copyright ownership. The ASF licenses this file | ||
| // to you under the Apache License, Version 2.0 (the | ||
| // "License"); you may not use this file except in compliance | ||
| // with the License. You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, | ||
| // software distributed under the License is distributed on an | ||
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| // KIND, either express or implied. See the License for the | ||
| // specific language governing permissions and limitations | ||
| // under the License. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <xsimd/xsimd.hpp> | ||
|
|
||
| #include <algorithm> | ||
| #include <cstdint> | ||
| #include <limits> | ||
|
|
||
| #include "parquet/level_comparison.h" | ||
|
|
||
| namespace parquet::internal { | ||
|
|
||
| template <typename Arch> | ||
| MinMax FindMinMaxSimd(const int16_t* levels, int64_t num_levels) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AntoinePrv Do you want to take a look at this implementation?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks reasonable to me. Cannot say if it is optimal (perhaps a manual unroll could help because of the loop-carried dependency, but perhaps the compiler can tell it is associative), but if it improves then it's good!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ursabot never finished, so please run I would like to see some independent numbers.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Result e-mails didn't get sent, but the results are here: |
||
| using batch = xsimd::batch<int16_t, Arch>; | ||
| constexpr int64_t kLanes = static_cast<int64_t>(batch::size); | ||
|
|
||
| MinMax out{std::numeric_limits<int16_t>::max(), std::numeric_limits<int16_t>::min()}; | ||
|
|
||
| int64_t i = 0; | ||
| if (num_levels >= kLanes) { | ||
| batch vmin(out.min); | ||
| batch vmax(out.max); | ||
| for (; i + kLanes <= num_levels; i += kLanes) { | ||
| const auto v = batch::load_unaligned(levels + i); | ||
| vmin = xsimd::min(vmin, v); | ||
| vmax = xsimd::max(vmax, v); | ||
| } | ||
| out.min = xsimd::reduce_min(vmin); | ||
| out.max = xsimd::reduce_max(vmax); | ||
| } | ||
| for (; i < num_levels; ++i) { | ||
| out.min = std::min(levels[i], out.min); | ||
| out.max = std::max(levels[i], out.max); | ||
| } | ||
| return out; | ||
| } | ||
|
|
||
| } // namespace parquet::internal | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
FindMinMaxImplstill in the codebase? If so, can we remove it?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It cannot be removed, ARROW_USER_SIMD_LEVEL=NONE would still require it.