You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by al...@apache.org on 2020/03/20 22:55:46 UTC
[kudu] 02/03: client: micro-optimize result batch cell getters by
outlining cold path
This is an automated email from the ASF dual-hosted git repository.
alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
commit d3b55212b9fdecc1b66c5f1163e65ec654a7bb77
Author: Todd Lipcon <to...@apache.org>
AuthorDate: Fri Dec 20 15:25:52 2019 -0800
client: micro-optimize result batch cell getters by outlining cold path
This improves performance in a couple ways:
- by outlining the Substitute call and Status construction, the
templated Get<TypeTraits> function becomes much smaller. This makes it
get inlined into the GetInt8(), GetInt32(), etc outer functions. So,
every call into those functions is just a single call instead of two
calls in short succession. This makes branch prediction easier.
- The addition of PREDICT_FALSE means the common path is now the
"straight line" path which means that a tight loop calling these
functions may be able to entirely fit within the micro-op cache, etc.
Details here are a bit black magic but it's generally considered good
hygiene for short loops to minimize the code footprint.
- The outlining of the call also means the stack frame size is a bit
smaller. The new code path has three "push" and "pop" instructions in
the function intro/outro whereas the old one had 6.
This improved TSBS perf about 10% for one of the workloads.
Change-Id: I5838576b3e18cbe8e093bf1e9ce6418ce922de63
Reviewed-on: http://gerrit.cloudera.org:8080/15503
Reviewed-by: Alexey Serbin <as...@cloudera.com>
Tested-by: Todd Lipcon <to...@apache.org>
---
src/kudu/client/scan_batch.cc | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/src/kudu/client/scan_batch.cc b/src/kudu/client/scan_batch.cc
index 324d01b..6f3c278 100644
--- a/src/kudu/client/scan_batch.cc
+++ b/src/kudu/client/scan_batch.cc
@@ -95,6 +95,12 @@ class RowCell {
const int col_idx_;
};
+Status BadTypeStatus(const char* provided_type_name, const ColumnSchema& col) {
+ return Status::InvalidArgument(
+ Substitute("invalid type $0 provided for column '$1' (expected $2)",
+ provided_type_name, col.name(), col.type_info()->name()));
+}
+
} // anonymous namespace
bool KuduScanBatch::RowPtr::IsNull(int col_idx) const {
@@ -233,14 +239,13 @@ template<typename T>
Status KuduScanBatch::RowPtr::Get(int col_idx, typename T::cpp_type* val) const {
const ColumnSchema& col = schema_->column(col_idx);
if (PREDICT_FALSE(col.type_info()->type() != T::type)) {
- // TODO: at some point we could allow type coercion here.
- return Status::InvalidArgument(
- Substitute("invalid type $0 provided for column '$1' (expected $2)",
- T::name(),
- col.name(), col.type_info()->name()));
+ // TODO(todd): at some point we could allow type coercion here.
+ // Explicitly out-of-line the construction of this Status in order to
+ // keep the getter code footprint as small as possible.
+ return BadTypeStatus(T::name(), col);
}
- if (col.is_nullable() && IsNull(col_idx)) {
+ if (PREDICT_FALSE(col.is_nullable() && IsNull(col_idx))) {
return Status::NotFound("column is NULL");
}