This is an automated email from the ASF dual-hosted git repository.
Mryange pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new aa95d10dc7d [opt](expr) Improve scalar function auto-vectorization
(#65908)
aa95d10dc7d is described below
commit aa95d10dc7df6262c829a0d6980a81d74b83a539
Author: Mryange <[email protected]>
AuthorDate: Wed Jul 29 11:13:37 2026 +0800
[opt](expr) Improve scalar function auto-vectorization (#65908)
### What problem does this PR solve?
Issue Number: N/A
Problem Summary:
Several scalar-function hot loops repeatedly extracted constant-column
values, performed branchy
null-map writes, or accessed `PODArray` through wrapper methods on every
row. These loop shapes
prevented Clang from generating efficient vector code.
This change hoists invariant bit and bit-shift operands out of the
loops, writes nullable math
predicates unconditionally, and obtains raw input and output pointers
before the `width_bucket`
loop. Focused benchmarks showed approximately 92%-98% lower CPU time for
constant bit operations,
28%-94% lower CPU time for nullable math null-map generation, and 3%-9%
lower CPU time for Float32
`width_bucket`.
### Release note
None
### Check List (For Author)
- Test <!-- At least one of them must be included. -->
- [ ] Regression test
- [ ] Unit Test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [ ] Previous test can cover this change.
- [ ] No code files have been changed.
- [ ] Other reason <!-- Add your reason? -->
- Behavior changed:
- [ ] No.
- [ ] Yes. <!-- Explain the behavior change -->
- Does this need documentation?
- [ ] No.
- [ ] Yes. <!-- Add document PR link here. eg:
https://github.com/apache/doris-website/pull/1214 -->
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label <!-- Add branch pick label that this PR
should merge into -->
---
be/src/exprs/function/function_bit.cpp | 6 ++++--
be/src/exprs/function/function_bit_shift.cpp | 6 ++++--
.../function/function_math_unary_alway_nullable.h | 8 ++++----
be/src/exprs/function/function_width_bucket.cpp | 20 +++++++++++---------
4 files changed, 23 insertions(+), 17 deletions(-)
diff --git a/be/src/exprs/function/function_bit.cpp
b/be/src/exprs/function/function_bit.cpp
index 2cf72dbe530..9b0ab7c229e 100644
--- a/be/src/exprs/function/function_bit.cpp
+++ b/be/src/exprs/function/function_bit.cpp
@@ -100,8 +100,9 @@ private:
auto& a = column_left_ptr->get_data();
auto& c = column_result->get_data();
size_t size = a.size();
+ const auto right_value = column_right_ptr->template
get_value<Impl::ArgPType>();
for (size_t i = 0; i < size; ++i) {
- c[i] = Impl::apply(a[i], column_right_ptr->template
get_value<Impl::ArgPType>());
+ c[i] = Impl::apply(a[i], right_value);
}
return column_result;
}
@@ -116,8 +117,9 @@ private:
auto& b = column_right_ptr->get_data();
auto& c = column_result->get_data();
size_t size = b.size();
+ const auto left_value = column_left_ptr->template
get_value<Impl::ArgPType>();
for (size_t i = 0; i < size; ++i) {
- c[i] = Impl::apply(column_left_ptr->template
get_value<Impl::ArgPType>(), b[i]);
+ c[i] = Impl::apply(left_value, b[i]);
}
return column_result;
}
diff --git a/be/src/exprs/function/function_bit_shift.cpp
b/be/src/exprs/function/function_bit_shift.cpp
index ec275146098..9e90992daa6 100644
--- a/be/src/exprs/function/function_bit_shift.cpp
+++ b/be/src/exprs/function/function_bit_shift.cpp
@@ -88,8 +88,9 @@ private:
auto& a = column_left_ptr->get_data();
auto& c = column_result->get_data();
size_t size = a.size();
+ const auto right_value = column_right_ptr->template
get_value<TYPE_TINYINT>();
for (size_t i = 0; i < size; ++i) {
- c[i] = Impl::apply(a[i], column_right_ptr->template
get_value<TYPE_TINYINT>());
+ c[i] = Impl::apply(a[i], right_value);
}
return column_result;
}
@@ -102,8 +103,9 @@ private:
auto& b = column_right_ptr->get_data();
auto& c = column_result->get_data();
size_t size = b.size();
+ const auto left_value = column_left_ptr->template
get_value<TYPE_BIGINT>();
for (size_t i = 0; i < size; ++i) {
- c[i] = Impl::apply(column_left_ptr->template
get_value<TYPE_BIGINT>(), b[i]);
+ c[i] = Impl::apply(left_value, b[i]);
}
return column_result;
}
diff --git a/be/src/exprs/function/function_math_unary_alway_nullable.h
b/be/src/exprs/function/function_math_unary_alway_nullable.h
index 174ea6a5e54..879a17c3edd 100644
--- a/be/src/exprs/function/function_math_unary_alway_nullable.h
+++ b/be/src/exprs/function/function_math_unary_alway_nullable.h
@@ -61,14 +61,14 @@ private:
auto& dst_data = dst->get_data();
dst_data.resize(input_rows_count);
- execute_in_iterations(col->get_data().data(), dst_data.data(),
input_rows_count);
+ const auto* input_data = col->get_data().data();
+ execute_in_iterations(input_data, dst_data.data(), input_rows_count);
auto result_null_map = ColumnUInt8::create(input_rows_count, 0);
+ auto* result_null_map_data = result_null_map->get_data().data();
for (size_t i = 0; i < input_rows_count; i++) {
- if (Impl::is_invalid_input(col->get_data()[i])) [[unlikely]] {
- result_null_map->get_data().data()[i] = 1;
- }
+ result_null_map_data[i] = Impl::is_invalid_input(input_data[i]);
}
block.replace_by_position(
diff --git a/be/src/exprs/function/function_width_bucket.cpp
b/be/src/exprs/function/function_width_bucket.cpp
index 5546dd051d2..f9660551b99 100644
--- a/be/src/exprs/function/function_width_bucket.cpp
+++ b/be/src/exprs/function/function_width_bucket.cpp
@@ -101,22 +101,24 @@ private:
auto& nested_column_concrete = *nested_column;
size_t input_rows_count = expr_column.size();
+ const auto* expr_data = expr_column_concrete.get_data().data();
+ const auto* min_value_data =
min_value_column_concrete.get_data().data();
+ const auto* max_value_data =
max_value_column_concrete.get_data().data();
+ auto* nested_data = nested_column_concrete.get_data().data();
for (size_t i = 0; i < input_rows_count; ++i) {
- auto min_value = min_value_column_concrete.get_data()[i];
- auto max_value = max_value_column_concrete.get_data()[i];
+ auto min_value = min_value_data[i];
+ auto max_value = max_value_data[i];
auto average_value = (max_value - min_value) / (1.0 * num_buckets);
- if (expr_column_concrete.get_data()[i] < min_value) {
+ if (expr_data[i] < min_value) {
continue;
- } else if (expr_column_concrete.get_data()[i] >= max_value) {
- nested_column_concrete.get_data()[i] = num_buckets + 1;
+ } else if (expr_data[i] >= max_value) {
+ nested_data[i] = num_buckets + 1;
} else {
if ((max_value - min_value) / num_buckets == 0) {
continue;
}
- nested_column_concrete.get_data()[i] =
- (int64_t)(1 +
- (expr_column_concrete.get_data()[i] -
min_value) / average_value);
+ nested_data[i] = (int64_t)(1 + (expr_data[i] - min_value) /
average_value);
}
}
}
@@ -162,4 +164,4 @@ void register_function_width_bucket(SimpleFunctionFactory&
factory) {
factory.register_function<FunctionWidthBucket>();
}
-} // namespace doris
\ No newline at end of file
+} // namespace doris
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]