You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ap...@apache.org on 2020/04/18 10:21:18 UTC

[arrow] branch master updated: ARROW-8496: [C++] Refine ByteStreamSplitDecodeScalar

This is an automated email from the ASF dual-hosted git repository.

apitrou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new d3a9a84  ARROW-8496: [C++] Refine ByteStreamSplitDecodeScalar
d3a9a84 is described below

commit d3a9a84f97ef890a3f5d10bcd6fca407919c4cbf
Author: Yibo Cai <yi...@arm.com>
AuthorDate: Sat Apr 18 12:20:59 2020 +0200

    ARROW-8496: [C++] Refine ByteStreamSplitDecodeScalar
    
    I simplified DecoderScalar code and see huge performance boost from
    clang generated code. Per my test on Intel E5-2650 with clang-9,
    Decode_Float_Scalar test jumps from 600M/s to 20G/s, even better
    than SSE version(17G/s). Similar behaviour observed on Arm64.
    
    Some digging shows clang auto vectorized the simplified decoder code,
    but gcc cannot: https://godbolt.org/z/kq9FAs
    Interestingly, gcc is able to auto vectorize EncoderFloatScalar code,
    but clang cannot: https://godbolt.org/z/E3LnZD
    
    NOTE: This scalar code is not tested in default x86_64 build, which
    goes the SSE version. Arm64 build goes this scalar code path.
    
    Closes #6962 from cyb70289/bytesplit
    
    Authored-by: Yibo Cai <yi...@arm.com>
    Signed-off-by: Antoine Pitrou <an...@python.org>
---
 cpp/src/arrow/util/byte_stream_split.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/cpp/src/arrow/util/byte_stream_split.h b/cpp/src/arrow/util/byte_stream_split.h
index eff595e..46be2e7 100644
--- a/cpp/src/arrow/util/byte_stream_split.h
+++ b/cpp/src/arrow/util/byte_stream_split.h
@@ -595,14 +595,13 @@ template <typename T>
 void ByteStreamSplitDecodeScalar(const uint8_t* data, int64_t num_values, int64_t stride,
                                  T* out) {
   constexpr size_t kNumStreams = sizeof(T);
+  auto output_buffer_raw = reinterpret_cast<uint8_t*>(out);
 
   for (int64_t i = 0; i < num_values; ++i) {
-    uint8_t gathered_byte_data[kNumStreams];
     for (size_t b = 0; b < kNumStreams; ++b) {
       const size_t byte_index = b * stride + i;
-      gathered_byte_data[b] = data[byte_index];
+      output_buffer_raw[i * kNumStreams + b] = data[byte_index];
     }
-    out[i] = arrow::util::SafeLoadAs<T>(&gathered_byte_data[0]);
   }
 }