be/src/util/frame_of_reference_coding.cpp
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #include "util/frame_of_reference_coding.h" |
19 | | |
20 | | #include <glog/logging.h> |
21 | | #include <sys/types.h> |
22 | | |
23 | | #include <algorithm> |
24 | | #include <cstring> |
25 | | #include <iostream> |
26 | | #include <iterator> |
27 | | #include <limits> |
28 | | |
29 | | #include "common/cast_set.h" |
30 | | #include "exec/common/endian.h" |
31 | | #include "util/bit_util.h" |
32 | | #include "util/coding.h" |
33 | | |
34 | | namespace doris { |
35 | | |
36 | | template <typename T> |
37 | 8.35M | const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) { |
38 | 8.35M | memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T)); |
39 | 8.35M | _buffered_values_num += count; |
40 | 8.35M | p_data += count; |
41 | 8.35M | return p_data; |
42 | 8.35M | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE10copy_valueEPKam Unexecuted instantiation: _ZN5doris10ForEncoderIsE10copy_valueEPKsm _ZN5doris10ForEncoderIiE10copy_valueEPKim Line | Count | Source | 37 | 16 | const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) { | 38 | 16 | memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T)); | 39 | 16 | _buffered_values_num += count; | 40 | 16 | p_data += count; | 41 | 16 | return p_data; | 42 | 16 | } |
_ZN5doris10ForEncoderIlE10copy_valueEPKlm Line | Count | Source | 37 | 4.17M | const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) { | 38 | 4.17M | memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T)); | 39 | 4.17M | _buffered_values_num += count; | 40 | 4.17M | p_data += count; | 41 | 4.17M | return p_data; | 42 | 4.17M | } |
_ZN5doris10ForEncoderInE10copy_valueEPKnm Line | Count | Source | 37 | 4.17M | const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) { | 38 | 4.17M | memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T)); | 39 | 4.17M | _buffered_values_num += count; | 40 | 4.17M | p_data += count; | 41 | 4.17M | return p_data; | 42 | 4.17M | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10copy_valueEPKhm Unexecuted instantiation: _ZN5doris10ForEncoderItE10copy_valueEPKtm _ZN5doris10ForEncoderIjE10copy_valueEPKjm Line | Count | Source | 37 | 6 | const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) { | 38 | 6 | memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T)); | 39 | 6 | _buffered_values_num += count; | 40 | 6 | p_data += count; | 41 | 6 | return p_data; | 42 | 6 | } |
Unexecuted instantiation: _ZN5doris10ForEncoderImE10copy_valueEPKmm Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10copy_valueEPKS1_m Unexecuted instantiation: _ZN5doris10ForEncoderIoE10copy_valueEPKom |
43 | | |
44 | | template <typename T> |
45 | 8.35M | void ForEncoder<T>::put_batch(const T* in_data, size_t count) { |
46 | 8.35M | if (_buffered_values_num + count < FRAME_VALUE_NUM) { |
47 | 8.32M | copy_value(in_data, count); |
48 | 8.32M | _values_num += count; |
49 | 8.32M | return; |
50 | 8.32M | } |
51 | | |
52 | | // 1. padding one frame |
53 | 32.7k | size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num; |
54 | 32.7k | in_data = copy_value(in_data, padding_num); |
55 | 32.7k | bit_packing_one_frame_value(_buffered_values); |
56 | | |
57 | | // 2. process frame by frame |
58 | 32.7k | size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM; |
59 | 32.8k | for (size_t i = 0; i < frame_size; i++) { |
60 | | // directly encode value to the bit_writer, don't buffer the value |
61 | 16 | _buffered_values_num = FRAME_VALUE_NUM; |
62 | 16 | bit_packing_one_frame_value(in_data); |
63 | 16 | in_data += FRAME_VALUE_NUM; |
64 | 16 | } |
65 | | |
66 | | // 3. process remaining value |
67 | 32.7k | size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM; |
68 | 32.7k | if (remaining_num > 0) { |
69 | 8 | copy_value(in_data, remaining_num); |
70 | 8 | } |
71 | | |
72 | 32.7k | _values_num += count; |
73 | 32.7k | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE9put_batchEPKam Unexecuted instantiation: _ZN5doris10ForEncoderIsE9put_batchEPKsm _ZN5doris10ForEncoderIiE9put_batchEPKim Line | Count | Source | 45 | 14 | void ForEncoder<T>::put_batch(const T* in_data, size_t count) { | 46 | 14 | if (_buffered_values_num + count < FRAME_VALUE_NUM) { | 47 | 8 | copy_value(in_data, count); | 48 | 8 | _values_num += count; | 49 | 8 | return; | 50 | 8 | } | 51 | | | 52 | | // 1. padding one frame | 53 | 6 | size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num; | 54 | 6 | in_data = copy_value(in_data, padding_num); | 55 | 6 | bit_packing_one_frame_value(_buffered_values); | 56 | | | 57 | | // 2. process frame by frame | 58 | 6 | size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM; | 59 | 10 | for (size_t i = 0; i < frame_size; i++) { | 60 | | // directly encode value to the bit_writer, don't buffer the value | 61 | 4 | _buffered_values_num = FRAME_VALUE_NUM; | 62 | 4 | bit_packing_one_frame_value(in_data); | 63 | 4 | in_data += FRAME_VALUE_NUM; | 64 | 4 | } | 65 | | | 66 | | // 3. process remaining value | 67 | 6 | size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM; | 68 | 6 | if (remaining_num > 0) { | 69 | 2 | copy_value(in_data, remaining_num); | 70 | 2 | } | 71 | | | 72 | 6 | _values_num += count; | 73 | 6 | } |
_ZN5doris10ForEncoderIlE9put_batchEPKlm Line | Count | Source | 45 | 4.17M | void ForEncoder<T>::put_batch(const T* in_data, size_t count) { | 46 | 4.17M | if (_buffered_values_num + count < FRAME_VALUE_NUM) { | 47 | 4.16M | copy_value(in_data, count); | 48 | 4.16M | _values_num += count; | 49 | 4.16M | return; | 50 | 4.16M | } | 51 | | | 52 | | // 1. padding one frame | 53 | 16.3k | size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num; | 54 | 16.3k | in_data = copy_value(in_data, padding_num); | 55 | 16.3k | bit_packing_one_frame_value(_buffered_values); | 56 | | | 57 | | // 2. process frame by frame | 58 | 16.3k | size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM; | 59 | 16.3k | for (size_t i = 0; i < frame_size; i++) { | 60 | | // directly encode value to the bit_writer, don't buffer the value | 61 | 6 | _buffered_values_num = FRAME_VALUE_NUM; | 62 | 6 | bit_packing_one_frame_value(in_data); | 63 | 6 | in_data += FRAME_VALUE_NUM; | 64 | 6 | } | 65 | | | 66 | | // 3. process remaining value | 67 | 16.3k | size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM; | 68 | 16.3k | if (remaining_num > 0) { | 69 | 6 | copy_value(in_data, remaining_num); | 70 | 6 | } | 71 | | | 72 | 16.3k | _values_num += count; | 73 | 16.3k | } |
_ZN5doris10ForEncoderInE9put_batchEPKnm Line | Count | Source | 45 | 4.17M | void ForEncoder<T>::put_batch(const T* in_data, size_t count) { | 46 | 4.17M | if (_buffered_values_num + count < FRAME_VALUE_NUM) { | 47 | 4.16M | copy_value(in_data, count); | 48 | 4.16M | _values_num += count; | 49 | 4.16M | return; | 50 | 4.16M | } | 51 | | | 52 | | // 1. padding one frame | 53 | 16.3k | size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num; | 54 | 16.3k | in_data = copy_value(in_data, padding_num); | 55 | 16.3k | bit_packing_one_frame_value(_buffered_values); | 56 | | | 57 | | // 2. process frame by frame | 58 | 16.3k | size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM; | 59 | 16.3k | for (size_t i = 0; i < frame_size; i++) { | 60 | | // directly encode value to the bit_writer, don't buffer the value | 61 | 0 | _buffered_values_num = FRAME_VALUE_NUM; | 62 | 0 | bit_packing_one_frame_value(in_data); | 63 | 0 | in_data += FRAME_VALUE_NUM; | 64 | 0 | } | 65 | | | 66 | | // 3. process remaining value | 67 | 16.3k | size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM; | 68 | 16.3k | if (remaining_num > 0) { | 69 | 0 | copy_value(in_data, remaining_num); | 70 | 0 | } | 71 | | | 72 | 16.3k | _values_num += count; | 73 | 16.3k | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE9put_batchEPKhm Unexecuted instantiation: _ZN5doris10ForEncoderItE9put_batchEPKtm _ZN5doris10ForEncoderIjE9put_batchEPKjm Line | Count | Source | 45 | 6 | void ForEncoder<T>::put_batch(const T* in_data, size_t count) { | 46 | 6 | if (_buffered_values_num + count < FRAME_VALUE_NUM) { | 47 | 0 | copy_value(in_data, count); | 48 | 0 | _values_num += count; | 49 | 0 | return; | 50 | 0 | } | 51 | | | 52 | | // 1. padding one frame | 53 | 6 | size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num; | 54 | 6 | in_data = copy_value(in_data, padding_num); | 55 | 6 | bit_packing_one_frame_value(_buffered_values); | 56 | | | 57 | | // 2. process frame by frame | 58 | 6 | size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM; | 59 | 12 | for (size_t i = 0; i < frame_size; i++) { | 60 | | // directly encode value to the bit_writer, don't buffer the value | 61 | 6 | _buffered_values_num = FRAME_VALUE_NUM; | 62 | 6 | bit_packing_one_frame_value(in_data); | 63 | 6 | in_data += FRAME_VALUE_NUM; | 64 | 6 | } | 65 | | | 66 | | // 3. process remaining value | 67 | 6 | size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM; | 68 | 6 | if (remaining_num > 0) { | 69 | 0 | copy_value(in_data, remaining_num); | 70 | 0 | } | 71 | | | 72 | 6 | _values_num += count; | 73 | 6 | } |
Unexecuted instantiation: _ZN5doris10ForEncoderImE9put_batchEPKmm Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE9put_batchEPKS1_m Unexecuted instantiation: _ZN5doris10ForEncoderIoE9put_batchEPKom |
74 | | |
75 | | // todo(kks): improve this method by SIMD instructions |
76 | | |
77 | | template <typename T> |
78 | 30.6k | void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { |
79 | 30.6k | int64_t s = 0; |
80 | 30.6k | uint8_t output_mask = 255; |
81 | 30.6k | int tail_count = in_num & 7; // the remainder of in_num modulo 8 |
82 | 30.6k | int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8 |
83 | | |
84 | 475k | for (int i = 0; i < full_batch_size; i += 8) { |
85 | | // Put the 8 numbers in the input into s in order, each number occupies bit_width bit |
86 | 445k | s |= static_cast<int64_t>(input[i + 7]); |
87 | 445k | s |= (static_cast<int64_t>(input[i + 6])) << bit_width; |
88 | 445k | s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width); |
89 | 445k | s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width); |
90 | 445k | s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width); |
91 | 445k | s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width); |
92 | 445k | s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width); |
93 | 445k | s |= (static_cast<int64_t>(input[i])) << (7 * bit_width); |
94 | | |
95 | | // Starting with the highest valid bit, take out 8 bits in sequence |
96 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid |
97 | | // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end |
98 | 2.44M | for (int j = 0; j < bit_width; j++) { |
99 | 2.00M | output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask; |
100 | 2.00M | } |
101 | 445k | output += bit_width; |
102 | 445k | s = 0; |
103 | 445k | } |
104 | | |
105 | | // remainder |
106 | 30.6k | int byte = tail_count * bit_width; // How many bits are left to store |
107 | 30.6k | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input |
108 | | |
109 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit |
110 | 130k | for (int i = 0; i < tail_count; i++) { |
111 | 100k | s |= (static_cast<int64_t>(input[i + full_batch_size])) |
112 | 100k | << ((tail_count - i - 1) * bit_width); |
113 | 100k | } |
114 | | |
115 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end |
116 | 30.6k | s <<= (bytes << 3) - byte; |
117 | | |
118 | | // Starting with the highest valid bit, take out 8 bits in sequence |
119 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. |
120 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end |
121 | 96.8k | for (int i = 0; i < bytes; i++) { |
122 | 66.2k | output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask; |
123 | 66.2k | } |
124 | 30.6k | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE10bit_pack_8EPKahiPh Unexecuted instantiation: _ZN5doris10ForEncoderIsE10bit_pack_8EPKshiPh _ZN5doris10ForEncoderIiE10bit_pack_8EPKihiPh Line | Count | Source | 78 | 16 | void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 79 | 16 | int64_t s = 0; | 80 | 16 | uint8_t output_mask = 255; | 81 | 16 | int tail_count = in_num & 7; // the remainder of in_num modulo 8 | 82 | 16 | int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8 | 83 | | | 84 | 208 | for (int i = 0; i < full_batch_size; i += 8) { | 85 | | // Put the 8 numbers in the input into s in order, each number occupies bit_width bit | 86 | 192 | s |= static_cast<int64_t>(input[i + 7]); | 87 | 192 | s |= (static_cast<int64_t>(input[i + 6])) << bit_width; | 88 | 192 | s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width); | 89 | 192 | s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width); | 90 | 192 | s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width); | 91 | 192 | s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width); | 92 | 192 | s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width); | 93 | 192 | s |= (static_cast<int64_t>(input[i])) << (7 * bit_width); | 94 | | | 95 | | // Starting with the highest valid bit, take out 8 bits in sequence | 96 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 97 | | // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end | 98 | 384 | for (int j = 0; j < bit_width; j++) { | 99 | 192 | output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask; | 100 | 192 | } | 101 | 192 | output += bit_width; | 102 | 192 | s = 0; | 103 | 192 | } | 104 | | | 105 | | // remainder | 106 | 16 | int byte = tail_count * bit_width; // How many bits are left to store | 107 | 16 | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input | 108 | | | 109 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit | 110 | 20 | for (int i = 0; i < tail_count; i++) { | 111 | 4 | s |= (static_cast<int64_t>(input[i + full_batch_size])) | 112 | 4 | << ((tail_count - i - 1) * bit_width); | 113 | 4 | } | 114 | | | 115 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end | 116 | 16 | s <<= (bytes << 3) - byte; | 117 | | | 118 | | // Starting with the highest valid bit, take out 8 bits in sequence | 119 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. | 120 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end | 121 | 18 | for (int i = 0; i < bytes; i++) { | 122 | 2 | output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask; | 123 | 2 | } | 124 | 16 | } |
_ZN5doris10ForEncoderIlE10bit_pack_8EPKlhiPh Line | Count | Source | 78 | 6.10k | void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 79 | 6.10k | int64_t s = 0; | 80 | 6.10k | uint8_t output_mask = 255; | 81 | 6.10k | int tail_count = in_num & 7; // the remainder of in_num modulo 8 | 82 | 6.10k | int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8 | 83 | | | 84 | 69.8k | for (int i = 0; i < full_batch_size; i += 8) { | 85 | | // Put the 8 numbers in the input into s in order, each number occupies bit_width bit | 86 | 63.7k | s |= static_cast<int64_t>(input[i + 7]); | 87 | 63.7k | s |= (static_cast<int64_t>(input[i + 6])) << bit_width; | 88 | 63.7k | s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width); | 89 | 63.7k | s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width); | 90 | 63.7k | s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width); | 91 | 63.7k | s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width); | 92 | 63.7k | s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width); | 93 | 63.7k | s |= (static_cast<int64_t>(input[i])) << (7 * bit_width); | 94 | | | 95 | | // Starting with the highest valid bit, take out 8 bits in sequence | 96 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 97 | | // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end | 98 | 349k | for (int j = 0; j < bit_width; j++) { | 99 | 285k | output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask; | 100 | 285k | } | 101 | 63.7k | output += bit_width; | 102 | 63.7k | s = 0; | 103 | 63.7k | } | 104 | | | 105 | | // remainder | 106 | 6.10k | int byte = tail_count * bit_width; // How many bits are left to store | 107 | 6.10k | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input | 108 | | | 109 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit | 110 | 20.4k | for (int i = 0; i < tail_count; i++) { | 111 | 14.3k | s |= (static_cast<int64_t>(input[i + full_batch_size])) | 112 | 14.3k | << ((tail_count - i - 1) * bit_width); | 113 | 14.3k | } | 114 | | | 115 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end | 116 | 6.10k | s <<= (bytes << 3) - byte; | 117 | | | 118 | | // Starting with the highest valid bit, take out 8 bits in sequence | 119 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. | 120 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end | 121 | 15.5k | for (int i = 0; i < bytes; i++) { | 122 | 9.44k | output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask; | 123 | 9.44k | } | 124 | 6.10k | } |
_ZN5doris10ForEncoderInE10bit_pack_8EPKnhiPh Line | Count | Source | 78 | 24.4k | void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 79 | 24.4k | int64_t s = 0; | 80 | 24.4k | uint8_t output_mask = 255; | 81 | 24.4k | int tail_count = in_num & 7; // the remainder of in_num modulo 8 | 82 | 24.4k | int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8 | 83 | | | 84 | 405k | for (int i = 0; i < full_batch_size; i += 8) { | 85 | | // Put the 8 numbers in the input into s in order, each number occupies bit_width bit | 86 | 380k | s |= static_cast<int64_t>(input[i + 7]); | 87 | 380k | s |= (static_cast<int64_t>(input[i + 6])) << bit_width; | 88 | 380k | s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width); | 89 | 380k | s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width); | 90 | 380k | s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width); | 91 | 380k | s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width); | 92 | 380k | s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width); | 93 | 380k | s |= (static_cast<int64_t>(input[i])) << (7 * bit_width); | 94 | | | 95 | | // Starting with the highest valid bit, take out 8 bits in sequence | 96 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 97 | | // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end | 98 | 2.09M | for (int j = 0; j < bit_width; j++) { | 99 | 1.71M | output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask; | 100 | 1.71M | } | 101 | 380k | output += bit_width; | 102 | 380k | s = 0; | 103 | 380k | } | 104 | | | 105 | | // remainder | 106 | 24.4k | int byte = tail_count * bit_width; // How many bits are left to store | 107 | 24.4k | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input | 108 | | | 109 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit | 110 | 110k | for (int i = 0; i < tail_count; i++) { | 111 | 86.0k | s |= (static_cast<int64_t>(input[i + full_batch_size])) | 112 | 86.0k | << ((tail_count - i - 1) * bit_width); | 113 | 86.0k | } | 114 | | | 115 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end | 116 | 24.4k | s <<= (bytes << 3) - byte; | 117 | | | 118 | | // Starting with the highest valid bit, take out 8 bits in sequence | 119 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. | 120 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end | 121 | 81.3k | for (int i = 0; i < bytes; i++) { | 122 | 56.8k | output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask; | 123 | 56.8k | } | 124 | 24.4k | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10bit_pack_8EPKhhiPh Unexecuted instantiation: _ZN5doris10ForEncoderItE10bit_pack_8EPKthiPh _ZN5doris10ForEncoderIjE10bit_pack_8EPKjhiPh Line | Count | Source | 78 | 12 | void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 79 | 12 | int64_t s = 0; | 80 | 12 | uint8_t output_mask = 255; | 81 | 12 | int tail_count = in_num & 7; // the remainder of in_num modulo 8 | 82 | 12 | int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8 | 83 | | | 84 | 204 | for (int i = 0; i < full_batch_size; i += 8) { | 85 | | // Put the 8 numbers in the input into s in order, each number occupies bit_width bit | 86 | 192 | s |= static_cast<int64_t>(input[i + 7]); | 87 | 192 | s |= (static_cast<int64_t>(input[i + 6])) << bit_width; | 88 | 192 | s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width); | 89 | 192 | s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width); | 90 | 192 | s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width); | 91 | 192 | s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width); | 92 | 192 | s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width); | 93 | 192 | s |= (static_cast<int64_t>(input[i])) << (7 * bit_width); | 94 | | | 95 | | // Starting with the highest valid bit, take out 8 bits in sequence | 96 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 97 | | // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end | 98 | 384 | for (int j = 0; j < bit_width; j++) { | 99 | 192 | output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask; | 100 | 192 | } | 101 | 192 | output += bit_width; | 102 | 192 | s = 0; | 103 | 192 | } | 104 | | | 105 | | // remainder | 106 | 12 | int byte = tail_count * bit_width; // How many bits are left to store | 107 | 12 | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input | 108 | | | 109 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit | 110 | 12 | for (int i = 0; i < tail_count; i++) { | 111 | 0 | s |= (static_cast<int64_t>(input[i + full_batch_size])) | 112 | 0 | << ((tail_count - i - 1) * bit_width); | 113 | 0 | } | 114 | | | 115 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end | 116 | 12 | s <<= (bytes << 3) - byte; | 117 | | | 118 | | // Starting with the highest valid bit, take out 8 bits in sequence | 119 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. | 120 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end | 121 | 12 | for (int i = 0; i < bytes; i++) { | 122 | 0 | output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask; | 123 | 0 | } | 124 | 12 | } |
Unexecuted instantiation: _ZN5doris10ForEncoderImE10bit_pack_8EPKmhiPh Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10bit_pack_8EPKS1_hiPh Unexecuted instantiation: _ZN5doris10ForEncoderIoE10bit_pack_8EPKohiPh |
125 | | |
126 | | template <typename T> |
127 | | template <typename U> |
128 | 91.6k | void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { |
129 | 91.6k | U s = 0; |
130 | 91.6k | uint8_t output_mask = 255; |
131 | 91.6k | int tail_count = in_num & 3; // the remainder of in_num modulo 4 |
132 | 91.6k | int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4 |
133 | 91.6k | int output_size = 0; // How many outputs can be processed at a time |
134 | 91.6k | int bit_width_remainder = |
135 | 91.6k | (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time |
136 | 91.6k | int extra_bit = 0; // Extra bits after each process |
137 | | |
138 | 2.80M | for (int i = 0; i < full_batch_size; i += 4) { |
139 | | // Put the 4 numbers in the input into s in order, each number occupies bit_width bit |
140 | | // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop |
141 | 2.70M | s <<= bit_width; |
142 | 2.70M | s |= (static_cast<U>(input[i])); |
143 | 2.70M | s <<= bit_width; |
144 | 2.70M | s |= (static_cast<U>(input[i + 1])); |
145 | 2.70M | s <<= bit_width; |
146 | 2.70M | s |= (static_cast<U>(input[i + 2])); |
147 | 2.70M | s <<= bit_width; |
148 | 2.70M | s |= (static_cast<U>(input[i + 3])); |
149 | | |
150 | | // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s, |
151 | | // and there are extra_bit bits left over from the last loop, |
152 | | // divide by 8 to calculate how much output can be processed in this loop. |
153 | 2.70M | output_size = ((bit_width << 2) + extra_bit) >> 3; |
154 | | |
155 | | // Each loop will leave bit_width_remainder bit unprocessed, |
156 | | // last loop will leave extra_bit bit, eventually will leave |
157 | | // (extra_bit + bit_width_remainder) & 7 bit unprocessed |
158 | 2.70M | extra_bit = (extra_bit + bit_width_remainder) & 7; |
159 | | |
160 | | // Starting with the highest valid bit, take out 8 bits in sequence |
161 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid |
162 | | // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end |
163 | | // But since there are still extra_bit bits that can't be processed, need to add the extra_bit |
164 | 30.4M | for (int j = 0; j < output_size; j++) { |
165 | 27.7M | output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask; |
166 | 27.7M | } |
167 | 2.70M | output += output_size; |
168 | | |
169 | | // s retains the post extra_bit bit as it is not processed |
170 | 2.70M | s &= (1 << extra_bit) - 1; |
171 | 2.70M | } |
172 | | |
173 | | // remainder |
174 | 91.6k | int byte = tail_count * bit_width; // How many bits are left to store |
175 | 91.6k | if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed |
176 | 91.6k | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input |
177 | | |
178 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit |
179 | 220k | for (int i = 0; i < tail_count; i++) { |
180 | 128k | s <<= bit_width; |
181 | 128k | s |= (input[i + full_batch_size]); |
182 | 128k | } |
183 | | |
184 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end |
185 | 91.6k | s <<= (bytes << 3) - byte; |
186 | | |
187 | | // Starting with the highest valid bit, take out 8 bits in sequence |
188 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. |
189 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end |
190 | 462k | for (int i = 0; i < bytes; i++) { |
191 | 370k | output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask; |
192 | 370k | } |
193 | 91.6k | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE10bit_pack_4IlEEvPKahiPh Unexecuted instantiation: _ZN5doris10ForEncoderIaE10bit_pack_4InEEvPKahiPh Unexecuted instantiation: _ZN5doris10ForEncoderIsE10bit_pack_4IlEEvPKshiPh Unexecuted instantiation: _ZN5doris10ForEncoderIsE10bit_pack_4InEEvPKshiPh Unexecuted instantiation: _ZN5doris10ForEncoderIiE10bit_pack_4IlEEvPKihiPh Unexecuted instantiation: _ZN5doris10ForEncoderIiE10bit_pack_4InEEvPKihiPh _ZN5doris10ForEncoderIlE10bit_pack_4IlEEvPKlhiPh Line | Count | Source | 128 | 6.07k | void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 129 | 6.07k | U s = 0; | 130 | 6.07k | uint8_t output_mask = 255; | 131 | 6.07k | int tail_count = in_num & 3; // the remainder of in_num modulo 4 | 132 | 6.07k | int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4 | 133 | 6.07k | int output_size = 0; // How many outputs can be processed at a time | 134 | 6.07k | int bit_width_remainder = | 135 | 6.07k | (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time | 136 | 6.07k | int extra_bit = 0; // Extra bits after each process | 137 | | | 138 | 135k | for (int i = 0; i < full_batch_size; i += 4) { | 139 | | // Put the 4 numbers in the input into s in order, each number occupies bit_width bit | 140 | | // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop | 141 | 129k | s <<= bit_width; | 142 | 129k | s |= (static_cast<U>(input[i])); | 143 | 129k | s <<= bit_width; | 144 | 129k | s |= (static_cast<U>(input[i + 1])); | 145 | 129k | s <<= bit_width; | 146 | 129k | s |= (static_cast<U>(input[i + 2])); | 147 | 129k | s <<= bit_width; | 148 | 129k | s |= (static_cast<U>(input[i + 3])); | 149 | | | 150 | | // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s, | 151 | | // and there are extra_bit bits left over from the last loop, | 152 | | // divide by 8 to calculate how much output can be processed in this loop. | 153 | 129k | output_size = ((bit_width << 2) + extra_bit) >> 3; | 154 | | | 155 | | // Each loop will leave bit_width_remainder bit unprocessed, | 156 | | // last loop will leave extra_bit bit, eventually will leave | 157 | | // (extra_bit + bit_width_remainder) & 7 bit unprocessed | 158 | 129k | extra_bit = (extra_bit + bit_width_remainder) & 7; | 159 | | | 160 | | // Starting with the highest valid bit, take out 8 bits in sequence | 161 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 162 | | // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end | 163 | | // But since there are still extra_bit bits that can't be processed, need to add the extra_bit | 164 | 934k | for (int j = 0; j < output_size; j++) { | 165 | 805k | output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask; | 166 | 805k | } | 167 | 129k | output += output_size; | 168 | | | 169 | | // s retains the post extra_bit bit as it is not processed | 170 | 129k | s &= (1 << extra_bit) - 1; | 171 | 129k | } | 172 | | | 173 | | // remainder | 174 | 6.07k | int byte = tail_count * bit_width; // How many bits are left to store | 175 | 6.07k | if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed | 176 | 6.07k | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input | 177 | | | 178 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit | 179 | 12.1k | for (int i = 0; i < tail_count; i++) { | 180 | 6.09k | s <<= bit_width; | 181 | 6.09k | s |= (input[i + full_batch_size]); | 182 | 6.09k | } | 183 | | | 184 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end | 185 | 6.07k | s <<= (bytes << 3) - byte; | 186 | | | 187 | | // Starting with the highest valid bit, take out 8 bits in sequence | 188 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. | 189 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end | 190 | 17.5k | for (int i = 0; i < bytes; i++) { | 191 | 11.4k | output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask; | 192 | 11.4k | } | 193 | 6.07k | } |
_ZN5doris10ForEncoderIlE10bit_pack_4InEEvPKlhiPh Line | Count | Source | 128 | 12.1k | void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 129 | 12.1k | U s = 0; | 130 | 12.1k | uint8_t output_mask = 255; | 131 | 12.1k | int tail_count = in_num & 3; // the remainder of in_num modulo 4 | 132 | 12.1k | int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4 | 133 | 12.1k | int output_size = 0; // How many outputs can be processed at a time | 134 | 12.1k | int bit_width_remainder = | 135 | 12.1k | (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time | 136 | 12.1k | int extra_bit = 0; // Extra bits after each process | 137 | | | 138 | 270k | for (int i = 0; i < full_batch_size; i += 4) { | 139 | | // Put the 4 numbers in the input into s in order, each number occupies bit_width bit | 140 | | // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop | 141 | 258k | s <<= bit_width; | 142 | 258k | s |= (static_cast<U>(input[i])); | 143 | 258k | s <<= bit_width; | 144 | 258k | s |= (static_cast<U>(input[i + 1])); | 145 | 258k | s <<= bit_width; | 146 | 258k | s |= (static_cast<U>(input[i + 2])); | 147 | 258k | s <<= bit_width; | 148 | 258k | s |= (static_cast<U>(input[i + 3])); | 149 | | | 150 | | // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s, | 151 | | // and there are extra_bit bits left over from the last loop, | 152 | | // divide by 8 to calculate how much output can be processed in this loop. | 153 | 258k | output_size = ((bit_width << 2) + extra_bit) >> 3; | 154 | | | 155 | | // Each loop will leave bit_width_remainder bit unprocessed, | 156 | | // last loop will leave extra_bit bit, eventually will leave | 157 | | // (extra_bit + bit_width_remainder) & 7 bit unprocessed | 158 | 258k | extra_bit = (extra_bit + bit_width_remainder) & 7; | 159 | | | 160 | | // Starting with the highest valid bit, take out 8 bits in sequence | 161 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 162 | | // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end | 163 | | // But since there are still extra_bit bits that can't be processed, need to add the extra_bit | 164 | 3.41M | for (int j = 0; j < output_size; j++) { | 165 | 3.16M | output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask; | 166 | 3.16M | } | 167 | 258k | output += output_size; | 168 | | | 169 | | // s retains the post extra_bit bit as it is not processed | 170 | 258k | s &= (1 << extra_bit) - 1; | 171 | 258k | } | 172 | | | 173 | | // remainder | 174 | 12.1k | int byte = tail_count * bit_width; // How many bits are left to store | 175 | 12.1k | if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed | 176 | 12.1k | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input | 177 | | | 178 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit | 179 | 24.4k | for (int i = 0; i < tail_count; i++) { | 180 | 12.2k | s <<= bit_width; | 181 | 12.2k | s |= (input[i + full_batch_size]); | 182 | 12.2k | } | 183 | | | 184 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end | 185 | 12.1k | s <<= (bytes << 3) - byte; | 186 | | | 187 | | // Starting with the highest valid bit, take out 8 bits in sequence | 188 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. | 189 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end | 190 | 53.4k | for (int i = 0; i < bytes; i++) { | 191 | 41.3k | output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask; | 192 | 41.3k | } | 193 | 12.1k | } |
_ZN5doris10ForEncoderInE10bit_pack_4IlEEvPKnhiPh Line | Count | Source | 128 | 24.4k | void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 129 | 24.4k | U s = 0; | 130 | 24.4k | uint8_t output_mask = 255; | 131 | 24.4k | int tail_count = in_num & 3; // the remainder of in_num modulo 4 | 132 | 24.4k | int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4 | 133 | 24.4k | int output_size = 0; // How many outputs can be processed at a time | 134 | 24.4k | int bit_width_remainder = | 135 | 24.4k | (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time | 136 | 24.4k | int extra_bit = 0; // Extra bits after each process | 137 | | | 138 | 798k | for (int i = 0; i < full_batch_size; i += 4) { | 139 | | // Put the 4 numbers in the input into s in order, each number occupies bit_width bit | 140 | | // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop | 141 | 774k | s <<= bit_width; | 142 | 774k | s |= (static_cast<U>(input[i])); | 143 | 774k | s <<= bit_width; | 144 | 774k | s |= (static_cast<U>(input[i + 1])); | 145 | 774k | s <<= bit_width; | 146 | 774k | s |= (static_cast<U>(input[i + 2])); | 147 | 774k | s <<= bit_width; | 148 | 774k | s |= (static_cast<U>(input[i + 3])); | 149 | | | 150 | | // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s, | 151 | | // and there are extra_bit bits left over from the last loop, | 152 | | // divide by 8 to calculate how much output can be processed in this loop. | 153 | 774k | output_size = ((bit_width << 2) + extra_bit) >> 3; | 154 | | | 155 | | // Each loop will leave bit_width_remainder bit unprocessed, | 156 | | // last loop will leave extra_bit bit, eventually will leave | 157 | | // (extra_bit + bit_width_remainder) & 7 bit unprocessed | 158 | 774k | extra_bit = (extra_bit + bit_width_remainder) & 7; | 159 | | | 160 | | // Starting with the highest valid bit, take out 8 bits in sequence | 161 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 162 | | // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end | 163 | | // But since there are still extra_bit bits that can't be processed, need to add the extra_bit | 164 | 5.60M | for (int j = 0; j < output_size; j++) { | 165 | 4.83M | output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask; | 166 | 4.83M | } | 167 | 774k | output += output_size; | 168 | | | 169 | | // s retains the post extra_bit bit as it is not processed | 170 | 774k | s &= (1 << extra_bit) - 1; | 171 | 774k | } | 172 | | | 173 | | // remainder | 174 | 24.4k | int byte = tail_count * bit_width; // How many bits are left to store | 175 | 24.4k | if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed | 176 | 24.4k | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input | 177 | | | 178 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit | 179 | 61.3k | for (int i = 0; i < tail_count; i++) { | 180 | 36.8k | s <<= bit_width; | 181 | 36.8k | s |= (input[i + full_batch_size]); | 182 | 36.8k | } | 183 | | | 184 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end | 185 | 24.4k | s <<= (bytes << 3) - byte; | 186 | | | 187 | | // Starting with the highest valid bit, take out 8 bits in sequence | 188 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. | 189 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end | 190 | 93.6k | for (int i = 0; i < bytes; i++) { | 191 | 69.1k | output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask; | 192 | 69.1k | } | 193 | 24.4k | } |
_ZN5doris10ForEncoderInE10bit_pack_4InEEvPKnhiPh Line | Count | Source | 128 | 48.9k | void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 129 | 48.9k | U s = 0; | 130 | 48.9k | uint8_t output_mask = 255; | 131 | 48.9k | int tail_count = in_num & 3; // the remainder of in_num modulo 4 | 132 | 48.9k | int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4 | 133 | 48.9k | int output_size = 0; // How many outputs can be processed at a time | 134 | 48.9k | int bit_width_remainder = | 135 | 48.9k | (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time | 136 | 48.9k | int extra_bit = 0; // Extra bits after each process | 137 | | | 138 | 1.59M | for (int i = 0; i < full_batch_size; i += 4) { | 139 | | // Put the 4 numbers in the input into s in order, each number occupies bit_width bit | 140 | | // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop | 141 | 1.54M | s <<= bit_width; | 142 | 1.54M | s |= (static_cast<U>(input[i])); | 143 | 1.54M | s <<= bit_width; | 144 | 1.54M | s |= (static_cast<U>(input[i + 1])); | 145 | 1.54M | s <<= bit_width; | 146 | 1.54M | s |= (static_cast<U>(input[i + 2])); | 147 | 1.54M | s <<= bit_width; | 148 | 1.54M | s |= (static_cast<U>(input[i + 3])); | 149 | | | 150 | | // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s, | 151 | | // and there are extra_bit bits left over from the last loop, | 152 | | // divide by 8 to calculate how much output can be processed in this loop. | 153 | 1.54M | output_size = ((bit_width << 2) + extra_bit) >> 3; | 154 | | | 155 | | // Each loop will leave bit_width_remainder bit unprocessed, | 156 | | // last loop will leave extra_bit bit, eventually will leave | 157 | | // (extra_bit + bit_width_remainder) & 7 bit unprocessed | 158 | 1.54M | extra_bit = (extra_bit + bit_width_remainder) & 7; | 159 | | | 160 | | // Starting with the highest valid bit, take out 8 bits in sequence | 161 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 162 | | // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end | 163 | | // But since there are still extra_bit bits that can't be processed, need to add the extra_bit | 164 | 20.5M | for (int j = 0; j < output_size; j++) { | 165 | 18.9M | output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask; | 166 | 18.9M | } | 167 | 1.54M | output += output_size; | 168 | | | 169 | | // s retains the post extra_bit bit as it is not processed | 170 | 1.54M | s &= (1 << extra_bit) - 1; | 171 | 1.54M | } | 172 | | | 173 | | // remainder | 174 | 48.9k | int byte = tail_count * bit_width; // How many bits are left to store | 175 | 48.9k | if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed | 176 | 48.9k | int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input | 177 | | | 178 | | // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit | 179 | 122k | for (int i = 0; i < tail_count; i++) { | 180 | 73.7k | s <<= bit_width; | 181 | 73.7k | s |= (input[i + full_batch_size]); | 182 | 73.7k | } | 183 | | | 184 | | // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end | 185 | 48.9k | s <<= (bytes << 3) - byte; | 186 | | | 187 | | // Starting with the highest valid bit, take out 8 bits in sequence | 188 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid. | 189 | | // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end | 190 | 297k | for (int i = 0; i < bytes; i++) { | 191 | 248k | output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask; | 192 | 248k | } | 193 | 48.9k | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10bit_pack_4IlEEvPKhhiPh Unexecuted instantiation: _ZN5doris10ForEncoderIhE10bit_pack_4InEEvPKhhiPh Unexecuted instantiation: _ZN5doris10ForEncoderItE10bit_pack_4IlEEvPKthiPh Unexecuted instantiation: _ZN5doris10ForEncoderItE10bit_pack_4InEEvPKthiPh Unexecuted instantiation: _ZN5doris10ForEncoderIjE10bit_pack_4IlEEvPKjhiPh Unexecuted instantiation: _ZN5doris10ForEncoderIjE10bit_pack_4InEEvPKjhiPh Unexecuted instantiation: _ZN5doris10ForEncoderImE10bit_pack_4IlEEvPKmhiPh Unexecuted instantiation: _ZN5doris10ForEncoderImE10bit_pack_4InEEvPKmhiPh Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10bit_pack_4IlEEvPKS1_hiPh Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10bit_pack_4InEEvPKS1_hiPh Unexecuted instantiation: _ZN5doris10ForEncoderIoE10bit_pack_4IlEEvPKohiPh Unexecuted instantiation: _ZN5doris10ForEncoderIoE10bit_pack_4InEEvPKohiPh |
194 | | |
195 | | template <typename T> |
196 | 363k | void ForEncoder<T>::bit_pack_1(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { |
197 | 363k | int output_mask = 255; |
198 | 363k | int need_bit = 0; // still need |
199 | | |
200 | 43.8M | for (int i = 0; i < in_num; i++) { |
201 | 43.4M | T x = input[i]; |
202 | 43.4M | int width = bit_width; |
203 | 43.4M | if (need_bit) { |
204 | | // The last time we take away the high 8 - need_bit, |
205 | | // we need to make up the rest of the need_bit from the width. |
206 | | // Use width - need_bit to compute high need_bit bits |
207 | 30.0M | *output |= x >> (width - need_bit); |
208 | 30.0M | output++; |
209 | | // There are need_bit bits being used, so subtract |
210 | 30.0M | width -= need_bit; |
211 | 30.0M | } |
212 | 43.4M | int num = width >> 3; // How many outputs can be processed at a time |
213 | 43.4M | int remainder = width & 7; // How many bits are left to store |
214 | | |
215 | | // Starting with the highest valid bit, take out 8 bits in sequence |
216 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid |
217 | | // (num-j-1)<<3 used to calculate how many bits need to be removed at the end |
218 | | // But since there are still remainder bits that can't be processed, need to add the remainder |
219 | 447M | for (int j = 0; j < num; j++) { |
220 | 404M | *output = cast_set<uint8_t>((x >> (((num - j - 1) << 3) + remainder)) & output_mask); |
221 | 404M | output++; |
222 | 404M | } |
223 | 43.4M | if (remainder) { |
224 | | // Process the last remaining remainder bit. |
225 | | // y = (x & ((1 << remainder) - 1)) extract the last remainder bits. |
226 | | // ouput = y << (8 - reaminder) Use the high 8 - remainder bit |
227 | 30.3M | *output = cast_set<uint8_t>((x & ((1 << remainder) - 1)) << (8 - remainder)); |
228 | | // Already have remainder bits, next time need 8-remainder bits |
229 | 30.3M | need_bit = 8 - remainder; |
230 | 30.3M | } else { |
231 | 13.1M | need_bit = 0; |
232 | 13.1M | } |
233 | 43.4M | } |
234 | 363k | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE10bit_pack_1EPKahiPh Unexecuted instantiation: _ZN5doris10ForEncoderIsE10bit_pack_1EPKshiPh Unexecuted instantiation: _ZN5doris10ForEncoderIiE10bit_pack_1EPKihiPh _ZN5doris10ForEncoderIlE10bit_pack_1EPKlhiPh Line | Count | Source | 196 | 24.3k | void ForEncoder<T>::bit_pack_1(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 197 | 24.3k | int output_mask = 255; | 198 | 24.3k | int need_bit = 0; // still need | 199 | | | 200 | 2.11M | for (int i = 0; i < in_num; i++) { | 201 | 2.08M | T x = input[i]; | 202 | 2.08M | int width = bit_width; | 203 | 2.08M | if (need_bit) { | 204 | | // The last time we take away the high 8 - need_bit, | 205 | | // we need to make up the rest of the need_bit from the width. | 206 | | // Use width - need_bit to compute high need_bit bits | 207 | 1.48M | *output |= x >> (width - need_bit); | 208 | 1.48M | output++; | 209 | | // There are need_bit bits being used, so subtract | 210 | 1.48M | width -= need_bit; | 211 | 1.48M | } | 212 | 2.08M | int num = width >> 3; // How many outputs can be processed at a time | 213 | 2.08M | int remainder = width & 7; // How many bits are left to store | 214 | | | 215 | | // Starting with the highest valid bit, take out 8 bits in sequence | 216 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 217 | | // (num-j-1)<<3 used to calculate how many bits need to be removed at the end | 218 | | // But since there are still remainder bits that can't be processed, need to add the remainder | 219 | 13.2M | for (int j = 0; j < num; j++) { | 220 | 11.1M | *output = cast_set<uint8_t>((x >> (((num - j - 1) << 3) + remainder)) & output_mask); | 221 | 11.1M | output++; | 222 | 11.1M | } | 223 | 2.08M | if (remainder) { | 224 | | // Process the last remaining remainder bit. | 225 | | // y = (x & ((1 << remainder) - 1)) extract the last remainder bits. | 226 | | // ouput = y << (8 - reaminder) Use the high 8 - remainder bit | 227 | 1.49M | *output = cast_set<uint8_t>((x & ((1 << remainder) - 1)) << (8 - remainder)); | 228 | | // Already have remainder bits, next time need 8-remainder bits | 229 | 1.49M | need_bit = 8 - remainder; | 230 | 1.49M | } else { | 231 | 589k | need_bit = 0; | 232 | 589k | } | 233 | 2.08M | } | 234 | 24.3k | } |
_ZN5doris10ForEncoderInE10bit_pack_1EPKnhiPh Line | Count | Source | 196 | 339k | void ForEncoder<T>::bit_pack_1(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 197 | 339k | int output_mask = 255; | 198 | 339k | int need_bit = 0; // still need | 199 | | | 200 | 41.7M | for (int i = 0; i < in_num; i++) { | 201 | 41.3M | T x = input[i]; | 202 | 41.3M | int width = bit_width; | 203 | 41.3M | if (need_bit) { | 204 | | // The last time we take away the high 8 - need_bit, | 205 | | // we need to make up the rest of the need_bit from the width. | 206 | | // Use width - need_bit to compute high need_bit bits | 207 | 28.6M | *output |= x >> (width - need_bit); | 208 | 28.6M | output++; | 209 | | // There are need_bit bits being used, so subtract | 210 | 28.6M | width -= need_bit; | 211 | 28.6M | } | 212 | 41.3M | int num = width >> 3; // How many outputs can be processed at a time | 213 | 41.3M | int remainder = width & 7; // How many bits are left to store | 214 | | | 215 | | // Starting with the highest valid bit, take out 8 bits in sequence | 216 | | // perform an AND operation with output_mask to ensure that only 8 bits are valid | 217 | | // (num-j-1)<<3 used to calculate how many bits need to be removed at the end | 218 | | // But since there are still remainder bits that can't be processed, need to add the remainder | 219 | 434M | for (int j = 0; j < num; j++) { | 220 | 393M | *output = cast_set<uint8_t>((x >> (((num - j - 1) << 3) + remainder)) & output_mask); | 221 | 393M | output++; | 222 | 393M | } | 223 | 41.3M | if (remainder) { | 224 | | // Process the last remaining remainder bit. | 225 | | // y = (x & ((1 << remainder) - 1)) extract the last remainder bits. | 226 | | // ouput = y << (8 - reaminder) Use the high 8 - remainder bit | 227 | 28.8M | *output = cast_set<uint8_t>((x & ((1 << remainder) - 1)) << (8 - remainder)); | 228 | | // Already have remainder bits, next time need 8-remainder bits | 229 | 28.8M | need_bit = 8 - remainder; | 230 | 28.8M | } else { | 231 | 12.5M | need_bit = 0; | 232 | 12.5M | } | 233 | 41.3M | } | 234 | 339k | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10bit_pack_1EPKhhiPh Unexecuted instantiation: _ZN5doris10ForEncoderItE10bit_pack_1EPKthiPh Unexecuted instantiation: _ZN5doris10ForEncoderIjE10bit_pack_1EPKjhiPh Unexecuted instantiation: _ZN5doris10ForEncoderImE10bit_pack_1EPKmhiPh Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10bit_pack_1EPKS1_hiPh Unexecuted instantiation: _ZN5doris10ForEncoderIoE10bit_pack_1EPKohiPh |
235 | | |
236 | | // Use as few bit as possible to store a piece of integer data. |
237 | | // param[in] input: the integer list need to pack |
238 | | // param[in] in_num: the number integer need to pack |
239 | | // param[in] bit_width: how many bit we use to store each integer data |
240 | | // param[out] out: the packed result |
241 | | |
242 | | // For example: |
243 | | // The input is int32 list: 1, 2, 4, 8 and bit_width is 4 |
244 | | // The output will be: 0001 0010 0100 1000 |
245 | | template <typename T> |
246 | 486k | void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { |
247 | 486k | if (in_num == 0 || bit_width == 0) { |
248 | 520 | return; |
249 | 520 | } |
250 | | /* |
251 | | bit_width <= 8 : pack_8 > pack_16 > pack_32 |
252 | | bit_width <= 16 : pack_4 > pack_8 > pack_16 |
253 | | bit_width <= 32 : pack_4 >= pack_2 > pack_8 |
254 | | (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently) |
255 | | bit_width <= 64 : pack_1 > pack_4 |
256 | | */ |
257 | 485k | if (bit_width <= 8) { |
258 | 30.6k | bit_pack_8(input, in_num, bit_width, output); |
259 | 455k | } else if (bit_width <= 16) { |
260 | 30.5k | bit_pack_4<int64_t>(input, in_num, bit_width, output); |
261 | 424k | } else if (bit_width <= 32) { |
262 | 61.1k | bit_pack_4<__int128_t>(input, in_num, bit_width, output); |
263 | 363k | } else { |
264 | 363k | bit_pack_1(input, in_num, bit_width, output); |
265 | 363k | } |
266 | 485k | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE8bit_packEPKahiPh Unexecuted instantiation: _ZN5doris10ForEncoderIsE8bit_packEPKshiPh _ZN5doris10ForEncoderIiE8bit_packEPKihiPh Line | Count | Source | 246 | 18 | void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 247 | 18 | if (in_num == 0 || bit_width == 0) { | 248 | 2 | return; | 249 | 2 | } | 250 | | /* | 251 | | bit_width <= 8 : pack_8 > pack_16 > pack_32 | 252 | | bit_width <= 16 : pack_4 > pack_8 > pack_16 | 253 | | bit_width <= 32 : pack_4 >= pack_2 > pack_8 | 254 | | (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently) | 255 | | bit_width <= 64 : pack_1 > pack_4 | 256 | | */ | 257 | 16 | if (bit_width <= 8) { | 258 | 16 | bit_pack_8(input, in_num, bit_width, output); | 259 | 16 | } else if (bit_width <= 16) { | 260 | 0 | bit_pack_4<int64_t>(input, in_num, bit_width, output); | 261 | 0 | } else if (bit_width <= 32) { | 262 | 0 | bit_pack_4<__int128_t>(input, in_num, bit_width, output); | 263 | 0 | } else { | 264 | 0 | bit_pack_1(input, in_num, bit_width, output); | 265 | 0 | } | 266 | 16 | } |
_ZN5doris10ForEncoderIlE8bit_packEPKlhiPh Line | Count | Source | 246 | 48.9k | void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 247 | 48.9k | if (in_num == 0 || bit_width == 0) { | 248 | 262 | return; | 249 | 262 | } | 250 | | /* | 251 | | bit_width <= 8 : pack_8 > pack_16 > pack_32 | 252 | | bit_width <= 16 : pack_4 > pack_8 > pack_16 | 253 | | bit_width <= 32 : pack_4 >= pack_2 > pack_8 | 254 | | (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently) | 255 | | bit_width <= 64 : pack_1 > pack_4 | 256 | | */ | 257 | 48.6k | if (bit_width <= 8) { | 258 | 6.10k | bit_pack_8(input, in_num, bit_width, output); | 259 | 42.5k | } else if (bit_width <= 16) { | 260 | 6.07k | bit_pack_4<int64_t>(input, in_num, bit_width, output); | 261 | 36.4k | } else if (bit_width <= 32) { | 262 | 12.1k | bit_pack_4<__int128_t>(input, in_num, bit_width, output); | 263 | 24.3k | } else { | 264 | 24.3k | bit_pack_1(input, in_num, bit_width, output); | 265 | 24.3k | } | 266 | 48.6k | } |
_ZN5doris10ForEncoderInE8bit_packEPKnhiPh Line | Count | Source | 246 | 437k | void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 247 | 437k | if (in_num == 0 || bit_width == 0) { | 248 | 256 | return; | 249 | 256 | } | 250 | | /* | 251 | | bit_width <= 8 : pack_8 > pack_16 > pack_32 | 252 | | bit_width <= 16 : pack_4 > pack_8 > pack_16 | 253 | | bit_width <= 32 : pack_4 >= pack_2 > pack_8 | 254 | | (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently) | 255 | | bit_width <= 64 : pack_1 > pack_4 | 256 | | */ | 257 | 437k | if (bit_width <= 8) { | 258 | 24.4k | bit_pack_8(input, in_num, bit_width, output); | 259 | 412k | } else if (bit_width <= 16) { | 260 | 24.4k | bit_pack_4<int64_t>(input, in_num, bit_width, output); | 261 | 388k | } else if (bit_width <= 32) { | 262 | 48.9k | bit_pack_4<__int128_t>(input, in_num, bit_width, output); | 263 | 339k | } else { | 264 | 339k | bit_pack_1(input, in_num, bit_width, output); | 265 | 339k | } | 266 | 437k | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE8bit_packEPKhhiPh Unexecuted instantiation: _ZN5doris10ForEncoderItE8bit_packEPKthiPh _ZN5doris10ForEncoderIjE8bit_packEPKjhiPh Line | Count | Source | 246 | 12 | void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) { | 247 | 12 | if (in_num == 0 || bit_width == 0) { | 248 | 0 | return; | 249 | 0 | } | 250 | | /* | 251 | | bit_width <= 8 : pack_8 > pack_16 > pack_32 | 252 | | bit_width <= 16 : pack_4 > pack_8 > pack_16 | 253 | | bit_width <= 32 : pack_4 >= pack_2 > pack_8 | 254 | | (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently) | 255 | | bit_width <= 64 : pack_1 > pack_4 | 256 | | */ | 257 | 12 | if (bit_width <= 8) { | 258 | 12 | bit_pack_8(input, in_num, bit_width, output); | 259 | 12 | } else if (bit_width <= 16) { | 260 | 0 | bit_pack_4<int64_t>(input, in_num, bit_width, output); | 261 | 0 | } else if (bit_width <= 32) { | 262 | 0 | bit_pack_4<__int128_t>(input, in_num, bit_width, output); | 263 | 0 | } else { | 264 | 0 | bit_pack_1(input, in_num, bit_width, output); | 265 | 0 | } | 266 | 12 | } |
Unexecuted instantiation: _ZN5doris10ForEncoderImE8bit_packEPKmhiPh Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE8bit_packEPKS1_hiPh Unexecuted instantiation: _ZN5doris10ForEncoderIoE8bit_packEPKohiPh |
267 | | |
268 | | template <typename T> |
269 | 97.8k | void ForEncoder<T>::bit_packing_one_frame_value(const T* input) { |
270 | 97.8k | T min = input[0]; |
271 | 97.8k | T max = input[0]; |
272 | 97.8k | bool is_ascending = true; |
273 | 97.8k | uint8_t bit_width = 0; |
274 | 97.8k | T half_max_delta = numeric_limits_max() >> 1; |
275 | 97.8k | bool is_keep_original_value = false; |
276 | | |
277 | | // 1. make sure order_flag, save_original_value, and find max&min. |
278 | 8.36M | for (uint8_t i = 1; i < _buffered_values_num; ++i) { |
279 | 8.26M | if (is_ascending) { |
280 | 172k | if (input[i] < input[i - 1]) { |
281 | 96.9k | is_ascending = false; |
282 | 96.9k | } else { |
283 | 76.0k | if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow |
284 | 0 | is_keep_original_value = true; |
285 | 76.0k | } else { |
286 | 76.0k | bit_width = std::max(bit_width, bits(input[i] - input[i - 1])); |
287 | 76.0k | } |
288 | 76.0k | } |
289 | 172k | } |
290 | | |
291 | 8.26M | if (input[i] < min) { |
292 | 361k | min = input[i]; |
293 | 361k | continue; |
294 | 361k | } |
295 | | |
296 | 7.90M | if (input[i] > max) { |
297 | 367k | max = input[i]; |
298 | 367k | } |
299 | 7.90M | } |
300 | 97.8k | if (!is_ascending) { |
301 | 96.9k | if ((max >> 1) - (min >> 1) > half_max_delta) { |
302 | 0 | is_keep_original_value = true; |
303 | 0 | } |
304 | 96.9k | } |
305 | | |
306 | | // 2. save min value. |
307 | 97.8k | if (sizeof(T) == 16) { |
308 | 48.8k | put_fixed128_le(_buffer, static_cast<uint128_t>(min)); |
309 | 48.9k | } else if (sizeof(T) == 8) { |
310 | 48.9k | put_fixed64_le(_buffer, static_cast<uint64_t>(min)); |
311 | 48.9k | } else { |
312 | 30 | put_fixed32_le(_buffer, static_cast<uint32_t>(min)); |
313 | 30 | } |
314 | | |
315 | | // 3.1 save original value. |
316 | 97.8k | if (is_keep_original_value) { |
317 | 0 | bit_width = sizeof(T) * 8; |
318 | 0 | uint32_t len = _buffered_values_num * bit_width; |
319 | 0 | _buffer->reserve(_buffer->size() + len); |
320 | 0 | size_t origin_size = _buffer->size(); |
321 | 0 | _buffer->resize(origin_size + len); |
322 | 0 | bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size); |
323 | 97.8k | } else { |
324 | | // 3.2 bit pack. |
325 | | // improve for ascending order input, we could use fewer bit |
326 | 97.8k | T delta_values[FRAME_VALUE_NUM]; |
327 | 97.8k | if (is_ascending) { |
328 | 898 | delta_values[0] = 0; |
329 | 6.34k | for (uint8_t i = 1; i < _buffered_values_num; ++i) { |
330 | 5.45k | delta_values[i] = input[i] - input[i - 1]; |
331 | 5.45k | } |
332 | 96.9k | } else { |
333 | 96.9k | bit_width = bits(static_cast<T>(max - min)); |
334 | 8.45M | for (uint8_t i = 0; i < _buffered_values_num; ++i) { |
335 | 8.35M | delta_values[i] = input[i] - min; |
336 | 8.35M | } |
337 | 96.9k | } |
338 | | |
339 | 97.8k | uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8); |
340 | | |
341 | 97.8k | _buffer->reserve(_buffer->size() + packing_len); |
342 | 97.8k | size_t origin_size = _buffer->size(); |
343 | 97.8k | _buffer->resize(origin_size + packing_len); |
344 | 97.8k | bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size); |
345 | 97.8k | } |
346 | 97.8k | uint8_t storage_format = 0; |
347 | 97.8k | if (is_keep_original_value) { |
348 | 0 | storage_format = 2; |
349 | 97.8k | } else if (is_ascending) { |
350 | 898 | storage_format = 1; |
351 | 898 | } |
352 | 97.8k | _storage_formats.push_back(storage_format); |
353 | 97.8k | _bit_widths.push_back(bit_width); |
354 | | |
355 | 97.8k | _buffered_values_num = 0; |
356 | 97.8k | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE27bit_packing_one_frame_valueEPKa Unexecuted instantiation: _ZN5doris10ForEncoderIsE27bit_packing_one_frame_valueEPKs _ZN5doris10ForEncoderIiE27bit_packing_one_frame_valueEPKi Line | Count | Source | 269 | 18 | void ForEncoder<T>::bit_packing_one_frame_value(const T* input) { | 270 | 18 | T min = input[0]; | 271 | 18 | T max = input[0]; | 272 | 18 | bool is_ascending = true; | 273 | 18 | uint8_t bit_width = 0; | 274 | 18 | T half_max_delta = numeric_limits_max() >> 1; | 275 | 18 | bool is_keep_original_value = false; | 276 | | | 277 | | // 1. make sure order_flag, save_original_value, and find max&min. | 278 | 1.54k | for (uint8_t i = 1; i < _buffered_values_num; ++i) { | 279 | 1.52k | if (is_ascending) { | 280 | 1.52k | if (input[i] < input[i - 1]) { | 281 | 0 | is_ascending = false; | 282 | 1.52k | } else { | 283 | 1.52k | if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow | 284 | 0 | is_keep_original_value = true; | 285 | 1.52k | } else { | 286 | 1.52k | bit_width = std::max(bit_width, bits(input[i] - input[i - 1])); | 287 | 1.52k | } | 288 | 1.52k | } | 289 | 1.52k | } | 290 | | | 291 | 1.52k | if (input[i] < min) { | 292 | 0 | min = input[i]; | 293 | 0 | continue; | 294 | 0 | } | 295 | | | 296 | 1.52k | if (input[i] > max) { | 297 | 1.52k | max = input[i]; | 298 | 1.52k | } | 299 | 1.52k | } | 300 | 18 | if (!is_ascending) { | 301 | 0 | if ((max >> 1) - (min >> 1) > half_max_delta) { | 302 | 0 | is_keep_original_value = true; | 303 | 0 | } | 304 | 0 | } | 305 | | | 306 | | // 2. save min value. | 307 | 18 | if (sizeof(T) == 16) { | 308 | 0 | put_fixed128_le(_buffer, static_cast<uint128_t>(min)); | 309 | 18 | } else if (sizeof(T) == 8) { | 310 | 0 | put_fixed64_le(_buffer, static_cast<uint64_t>(min)); | 311 | 18 | } else { | 312 | 18 | put_fixed32_le(_buffer, static_cast<uint32_t>(min)); | 313 | 18 | } | 314 | | | 315 | | // 3.1 save original value. | 316 | 18 | if (is_keep_original_value) { | 317 | 0 | bit_width = sizeof(T) * 8; | 318 | 0 | uint32_t len = _buffered_values_num * bit_width; | 319 | 0 | _buffer->reserve(_buffer->size() + len); | 320 | 0 | size_t origin_size = _buffer->size(); | 321 | 0 | _buffer->resize(origin_size + len); | 322 | 0 | bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size); | 323 | 18 | } else { | 324 | | // 3.2 bit pack. | 325 | | // improve for ascending order input, we could use fewer bit | 326 | 18 | T delta_values[FRAME_VALUE_NUM]; | 327 | 18 | if (is_ascending) { | 328 | 18 | delta_values[0] = 0; | 329 | 1.54k | for (uint8_t i = 1; i < _buffered_values_num; ++i) { | 330 | 1.52k | delta_values[i] = input[i] - input[i - 1]; | 331 | 1.52k | } | 332 | 18 | } else { | 333 | 0 | bit_width = bits(static_cast<T>(max - min)); | 334 | 0 | for (uint8_t i = 0; i < _buffered_values_num; ++i) { | 335 | 0 | delta_values[i] = input[i] - min; | 336 | 0 | } | 337 | 0 | } | 338 | | | 339 | 18 | uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8); | 340 | | | 341 | 18 | _buffer->reserve(_buffer->size() + packing_len); | 342 | 18 | size_t origin_size = _buffer->size(); | 343 | 18 | _buffer->resize(origin_size + packing_len); | 344 | 18 | bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size); | 345 | 18 | } | 346 | 18 | uint8_t storage_format = 0; | 347 | 18 | if (is_keep_original_value) { | 348 | 0 | storage_format = 2; | 349 | 18 | } else if (is_ascending) { | 350 | 18 | storage_format = 1; | 351 | 18 | } | 352 | 18 | _storage_formats.push_back(storage_format); | 353 | 18 | _bit_widths.push_back(bit_width); | 354 | | | 355 | 18 | _buffered_values_num = 0; | 356 | 18 | } |
_ZN5doris10ForEncoderIlE27bit_packing_one_frame_valueEPKl Line | Count | Source | 269 | 48.9k | void ForEncoder<T>::bit_packing_one_frame_value(const T* input) { | 270 | 48.9k | T min = input[0]; | 271 | 48.9k | T max = input[0]; | 272 | 48.9k | bool is_ascending = true; | 273 | 48.9k | uint8_t bit_width = 0; | 274 | 48.9k | T half_max_delta = numeric_limits_max() >> 1; | 275 | 48.9k | bool is_keep_original_value = false; | 276 | | | 277 | | // 1. make sure order_flag, save_original_value, and find max&min. | 278 | 4.17M | for (uint8_t i = 1; i < _buffered_values_num; ++i) { | 279 | 4.13M | if (is_ascending) { | 280 | 86.7k | if (input[i] < input[i - 1]) { | 281 | 48.4k | is_ascending = false; | 282 | 48.4k | } else { | 283 | 38.2k | if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow | 284 | 0 | is_keep_original_value = true; | 285 | 38.2k | } else { | 286 | 38.2k | bit_width = std::max(bit_width, bits(input[i] - input[i - 1])); | 287 | 38.2k | } | 288 | 38.2k | } | 289 | 86.7k | } | 290 | | | 291 | 4.13M | if (input[i] < min) { | 292 | 176k | min = input[i]; | 293 | 176k | continue; | 294 | 176k | } | 295 | | | 296 | 3.95M | if (input[i] > max) { | 297 | 179k | max = input[i]; | 298 | 179k | } | 299 | 3.95M | } | 300 | 48.9k | if (!is_ascending) { | 301 | 48.4k | if ((max >> 1) - (min >> 1) > half_max_delta) { | 302 | 0 | is_keep_original_value = true; | 303 | 0 | } | 304 | 48.4k | } | 305 | | | 306 | | // 2. save min value. | 307 | 48.9k | if (sizeof(T) == 16) { | 308 | 0 | put_fixed128_le(_buffer, static_cast<uint128_t>(min)); | 309 | 48.9k | } else if (sizeof(T) == 8) { | 310 | 48.9k | put_fixed64_le(_buffer, static_cast<uint64_t>(min)); | 311 | 48.9k | } else { | 312 | 0 | put_fixed32_le(_buffer, static_cast<uint32_t>(min)); | 313 | 0 | } | 314 | | | 315 | | // 3.1 save original value. | 316 | 48.9k | if (is_keep_original_value) { | 317 | 0 | bit_width = sizeof(T) * 8; | 318 | 0 | uint32_t len = _buffered_values_num * bit_width; | 319 | 0 | _buffer->reserve(_buffer->size() + len); | 320 | 0 | size_t origin_size = _buffer->size(); | 321 | 0 | _buffer->resize(origin_size + len); | 322 | 0 | bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size); | 323 | 48.9k | } else { | 324 | | // 3.2 bit pack. | 325 | | // improve for ascending order input, we could use fewer bit | 326 | 48.9k | T delta_values[FRAME_VALUE_NUM]; | 327 | 48.9k | if (is_ascending) { | 328 | 440 | delta_values[0] = 0; | 329 | 2.59k | for (uint8_t i = 1; i < _buffered_values_num; ++i) { | 330 | 2.15k | delta_values[i] = input[i] - input[i - 1]; | 331 | 2.15k | } | 332 | 48.4k | } else { | 333 | 48.4k | bit_width = bits(static_cast<T>(max - min)); | 334 | 4.22M | for (uint8_t i = 0; i < _buffered_values_num; ++i) { | 335 | 4.17M | delta_values[i] = input[i] - min; | 336 | 4.17M | } | 337 | 48.4k | } | 338 | | | 339 | 48.9k | uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8); | 340 | | | 341 | 48.9k | _buffer->reserve(_buffer->size() + packing_len); | 342 | 48.9k | size_t origin_size = _buffer->size(); | 343 | 48.9k | _buffer->resize(origin_size + packing_len); | 344 | 48.9k | bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size); | 345 | 48.9k | } | 346 | 48.9k | uint8_t storage_format = 0; | 347 | 48.9k | if (is_keep_original_value) { | 348 | 0 | storage_format = 2; | 349 | 48.9k | } else if (is_ascending) { | 350 | 440 | storage_format = 1; | 351 | 440 | } | 352 | 48.9k | _storage_formats.push_back(storage_format); | 353 | 48.9k | _bit_widths.push_back(bit_width); | 354 | | | 355 | 48.9k | _buffered_values_num = 0; | 356 | 48.9k | } |
_ZN5doris10ForEncoderInE27bit_packing_one_frame_valueEPKn Line | Count | Source | 269 | 48.8k | void ForEncoder<T>::bit_packing_one_frame_value(const T* input) { | 270 | 48.8k | T min = input[0]; | 271 | 48.8k | T max = input[0]; | 272 | 48.8k | bool is_ascending = true; | 273 | 48.8k | uint8_t bit_width = 0; | 274 | 48.8k | T half_max_delta = numeric_limits_max() >> 1; | 275 | 48.8k | bool is_keep_original_value = false; | 276 | | | 277 | | // 1. make sure order_flag, save_original_value, and find max&min. | 278 | 4.17M | for (uint8_t i = 1; i < _buffered_values_num; ++i) { | 279 | 4.12M | if (is_ascending) { | 280 | 83.1k | if (input[i] < input[i - 1]) { | 281 | 48.4k | is_ascending = false; | 282 | 48.4k | } else { | 283 | 34.7k | if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow | 284 | 0 | is_keep_original_value = true; | 285 | 34.7k | } else { | 286 | 34.7k | bit_width = std::max(bit_width, bits(input[i] - input[i - 1])); | 287 | 34.7k | } | 288 | 34.7k | } | 289 | 83.1k | } | 290 | | | 291 | 4.12M | if (input[i] < min) { | 292 | 185k | min = input[i]; | 293 | 185k | continue; | 294 | 185k | } | 295 | | | 296 | 3.94M | if (input[i] > max) { | 297 | 185k | max = input[i]; | 298 | 185k | } | 299 | 3.94M | } | 300 | 48.8k | if (!is_ascending) { | 301 | 48.4k | if ((max >> 1) - (min >> 1) > half_max_delta) { | 302 | 0 | is_keep_original_value = true; | 303 | 0 | } | 304 | 48.4k | } | 305 | | | 306 | | // 2. save min value. | 307 | 48.8k | if (sizeof(T) == 16) { | 308 | 48.8k | put_fixed128_le(_buffer, static_cast<uint128_t>(min)); | 309 | 48.8k | } else if (sizeof(T) == 8) { | 310 | 0 | put_fixed64_le(_buffer, static_cast<uint64_t>(min)); | 311 | 0 | } else { | 312 | 0 | put_fixed32_le(_buffer, static_cast<uint32_t>(min)); | 313 | 0 | } | 314 | | | 315 | | // 3.1 save original value. | 316 | 48.8k | if (is_keep_original_value) { | 317 | 0 | bit_width = sizeof(T) * 8; | 318 | 0 | uint32_t len = _buffered_values_num * bit_width; | 319 | 0 | _buffer->reserve(_buffer->size() + len); | 320 | 0 | size_t origin_size = _buffer->size(); | 321 | 0 | _buffer->resize(origin_size + len); | 322 | 0 | bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size); | 323 | 48.8k | } else { | 324 | | // 3.2 bit pack. | 325 | | // improve for ascending order input, we could use fewer bit | 326 | 48.8k | T delta_values[FRAME_VALUE_NUM]; | 327 | 48.8k | if (is_ascending) { | 328 | 428 | delta_values[0] = 0; | 329 | 676 | for (uint8_t i = 1; i < _buffered_values_num; ++i) { | 330 | 248 | delta_values[i] = input[i] - input[i - 1]; | 331 | 248 | } | 332 | 48.4k | } else { | 333 | 48.4k | bit_width = bits(static_cast<T>(max - min)); | 334 | 4.22M | for (uint8_t i = 0; i < _buffered_values_num; ++i) { | 335 | 4.17M | delta_values[i] = input[i] - min; | 336 | 4.17M | } | 337 | 48.4k | } | 338 | | | 339 | 48.8k | uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8); | 340 | | | 341 | 48.8k | _buffer->reserve(_buffer->size() + packing_len); | 342 | 48.8k | size_t origin_size = _buffer->size(); | 343 | 48.8k | _buffer->resize(origin_size + packing_len); | 344 | 48.8k | bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size); | 345 | 48.8k | } | 346 | 48.8k | uint8_t storage_format = 0; | 347 | 48.8k | if (is_keep_original_value) { | 348 | 0 | storage_format = 2; | 349 | 48.8k | } else if (is_ascending) { | 350 | 428 | storage_format = 1; | 351 | 428 | } | 352 | 48.8k | _storage_formats.push_back(storage_format); | 353 | 48.8k | _bit_widths.push_back(bit_width); | 354 | | | 355 | 48.8k | _buffered_values_num = 0; | 356 | 48.8k | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE27bit_packing_one_frame_valueEPKh Unexecuted instantiation: _ZN5doris10ForEncoderItE27bit_packing_one_frame_valueEPKt _ZN5doris10ForEncoderIjE27bit_packing_one_frame_valueEPKj Line | Count | Source | 269 | 12 | void ForEncoder<T>::bit_packing_one_frame_value(const T* input) { | 270 | 12 | T min = input[0]; | 271 | 12 | T max = input[0]; | 272 | 12 | bool is_ascending = true; | 273 | 12 | uint8_t bit_width = 0; | 274 | 12 | T half_max_delta = numeric_limits_max() >> 1; | 275 | 12 | bool is_keep_original_value = false; | 276 | | | 277 | | // 1. make sure order_flag, save_original_value, and find max&min. | 278 | 1.53k | for (uint8_t i = 1; i < _buffered_values_num; ++i) { | 279 | 1.52k | if (is_ascending) { | 280 | 1.52k | if (input[i] < input[i - 1]) { | 281 | 0 | is_ascending = false; | 282 | 1.52k | } else { | 283 | 1.52k | if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow | 284 | 0 | is_keep_original_value = true; | 285 | 1.52k | } else { | 286 | 1.52k | bit_width = std::max(bit_width, bits(input[i] - input[i - 1])); | 287 | 1.52k | } | 288 | 1.52k | } | 289 | 1.52k | } | 290 | | | 291 | 1.52k | if (input[i] < min) { | 292 | 0 | min = input[i]; | 293 | 0 | continue; | 294 | 0 | } | 295 | | | 296 | 1.52k | if (input[i] > max) { | 297 | 1.52k | max = input[i]; | 298 | 1.52k | } | 299 | 1.52k | } | 300 | 12 | if (!is_ascending) { | 301 | 0 | if ((max >> 1) - (min >> 1) > half_max_delta) { | 302 | 0 | is_keep_original_value = true; | 303 | 0 | } | 304 | 0 | } | 305 | | | 306 | | // 2. save min value. | 307 | 12 | if (sizeof(T) == 16) { | 308 | 0 | put_fixed128_le(_buffer, static_cast<uint128_t>(min)); | 309 | 12 | } else if (sizeof(T) == 8) { | 310 | 0 | put_fixed64_le(_buffer, static_cast<uint64_t>(min)); | 311 | 12 | } else { | 312 | 12 | put_fixed32_le(_buffer, static_cast<uint32_t>(min)); | 313 | 12 | } | 314 | | | 315 | | // 3.1 save original value. | 316 | 12 | if (is_keep_original_value) { | 317 | 0 | bit_width = sizeof(T) * 8; | 318 | 0 | uint32_t len = _buffered_values_num * bit_width; | 319 | 0 | _buffer->reserve(_buffer->size() + len); | 320 | 0 | size_t origin_size = _buffer->size(); | 321 | 0 | _buffer->resize(origin_size + len); | 322 | 0 | bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size); | 323 | 12 | } else { | 324 | | // 3.2 bit pack. | 325 | | // improve for ascending order input, we could use fewer bit | 326 | 12 | T delta_values[FRAME_VALUE_NUM]; | 327 | 12 | if (is_ascending) { | 328 | 12 | delta_values[0] = 0; | 329 | 1.53k | for (uint8_t i = 1; i < _buffered_values_num; ++i) { | 330 | 1.52k | delta_values[i] = input[i] - input[i - 1]; | 331 | 1.52k | } | 332 | 12 | } else { | 333 | 0 | bit_width = bits(static_cast<T>(max - min)); | 334 | 0 | for (uint8_t i = 0; i < _buffered_values_num; ++i) { | 335 | 0 | delta_values[i] = input[i] - min; | 336 | 0 | } | 337 | 0 | } | 338 | | | 339 | 12 | uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8); | 340 | | | 341 | 12 | _buffer->reserve(_buffer->size() + packing_len); | 342 | 12 | size_t origin_size = _buffer->size(); | 343 | 12 | _buffer->resize(origin_size + packing_len); | 344 | 12 | bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size); | 345 | 12 | } | 346 | 12 | uint8_t storage_format = 0; | 347 | 12 | if (is_keep_original_value) { | 348 | 0 | storage_format = 2; | 349 | 12 | } else if (is_ascending) { | 350 | 12 | storage_format = 1; | 351 | 12 | } | 352 | 12 | _storage_formats.push_back(storage_format); | 353 | 12 | _bit_widths.push_back(bit_width); | 354 | | | 355 | 12 | _buffered_values_num = 0; | 356 | 12 | } |
Unexecuted instantiation: _ZN5doris10ForEncoderImE27bit_packing_one_frame_valueEPKm Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE27bit_packing_one_frame_valueEPKS1_ Unexecuted instantiation: _ZN5doris10ForEncoderIoE27bit_packing_one_frame_valueEPKo |
357 | | |
358 | | template <typename T> |
359 | 65.3k | uint32_t ForEncoder<T>::flush() { |
360 | 65.3k | if (_buffered_values_num != 0) { |
361 | 65.0k | bit_packing_one_frame_value(_buffered_values); |
362 | 65.0k | } |
363 | | |
364 | | // write the footer: |
365 | | // 1 _storage_formats and bit_widths |
366 | 65.3k | DCHECK(_storage_formats.size() == _bit_widths.size()) |
367 | 0 | << "Size of _storage_formats and _bit_widths should be equal."; |
368 | 163k | for (size_t i = 0; i < _storage_formats.size(); i++) { |
369 | 97.8k | _buffer->append(&_storage_formats[i], 1); |
370 | 97.8k | _buffer->append(&_bit_widths[i], 1); |
371 | 97.8k | } |
372 | | // 2 frame_value_num and values_num |
373 | 65.3k | uint8_t frame_value_num = FRAME_VALUE_NUM; |
374 | 65.3k | _buffer->append(&frame_value_num, 1); |
375 | 65.3k | put_fixed32_le(_buffer, _values_num); |
376 | | |
377 | 65.3k | return cast_set<uint32_t>(_buffer->size()); |
378 | 65.3k | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE5flushEv Unexecuted instantiation: _ZN5doris10ForEncoderIsE5flushEv _ZN5doris10ForEncoderIiE5flushEv Line | Count | Source | 359 | 14 | uint32_t ForEncoder<T>::flush() { | 360 | 14 | if (_buffered_values_num != 0) { | 361 | 8 | bit_packing_one_frame_value(_buffered_values); | 362 | 8 | } | 363 | | | 364 | | // write the footer: | 365 | | // 1 _storage_formats and bit_widths | 366 | 14 | DCHECK(_storage_formats.size() == _bit_widths.size()) | 367 | 0 | << "Size of _storage_formats and _bit_widths should be equal."; | 368 | 32 | for (size_t i = 0; i < _storage_formats.size(); i++) { | 369 | 18 | _buffer->append(&_storage_formats[i], 1); | 370 | 18 | _buffer->append(&_bit_widths[i], 1); | 371 | 18 | } | 372 | | // 2 frame_value_num and values_num | 373 | 14 | uint8_t frame_value_num = FRAME_VALUE_NUM; | 374 | 14 | _buffer->append(&frame_value_num, 1); | 375 | 14 | put_fixed32_le(_buffer, _values_num); | 376 | | | 377 | 14 | return cast_set<uint32_t>(_buffer->size()); | 378 | 14 | } |
_ZN5doris10ForEncoderIlE5flushEv Line | Count | Source | 359 | 32.6k | uint32_t ForEncoder<T>::flush() { | 360 | 32.6k | if (_buffered_values_num != 0) { | 361 | 32.5k | bit_packing_one_frame_value(_buffered_values); | 362 | 32.5k | } | 363 | | | 364 | | // write the footer: | 365 | | // 1 _storage_formats and bit_widths | 366 | 32.6k | DCHECK(_storage_formats.size() == _bit_widths.size()) | 367 | 0 | << "Size of _storage_formats and _bit_widths should be equal."; | 368 | 81.5k | for (size_t i = 0; i < _storage_formats.size(); i++) { | 369 | 48.9k | _buffer->append(&_storage_formats[i], 1); | 370 | 48.9k | _buffer->append(&_bit_widths[i], 1); | 371 | 48.9k | } | 372 | | // 2 frame_value_num and values_num | 373 | 32.6k | uint8_t frame_value_num = FRAME_VALUE_NUM; | 374 | 32.6k | _buffer->append(&frame_value_num, 1); | 375 | 32.6k | put_fixed32_le(_buffer, _values_num); | 376 | | | 377 | 32.6k | return cast_set<uint32_t>(_buffer->size()); | 378 | 32.6k | } |
_ZN5doris10ForEncoderInE5flushEv Line | Count | Source | 359 | 32.6k | uint32_t ForEncoder<T>::flush() { | 360 | 32.6k | if (_buffered_values_num != 0) { | 361 | 32.5k | bit_packing_one_frame_value(_buffered_values); | 362 | 32.5k | } | 363 | | | 364 | | // write the footer: | 365 | | // 1 _storage_formats and bit_widths | 366 | 32.6k | DCHECK(_storage_formats.size() == _bit_widths.size()) | 367 | 0 | << "Size of _storage_formats and _bit_widths should be equal."; | 368 | 81.5k | for (size_t i = 0; i < _storage_formats.size(); i++) { | 369 | 48.8k | _buffer->append(&_storage_formats[i], 1); | 370 | 48.8k | _buffer->append(&_bit_widths[i], 1); | 371 | 48.8k | } | 372 | | // 2 frame_value_num and values_num | 373 | 32.6k | uint8_t frame_value_num = FRAME_VALUE_NUM; | 374 | 32.6k | _buffer->append(&frame_value_num, 1); | 375 | 32.6k | put_fixed32_le(_buffer, _values_num); | 376 | | | 377 | 32.6k | return cast_set<uint32_t>(_buffer->size()); | 378 | 32.6k | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE5flushEv Unexecuted instantiation: _ZN5doris10ForEncoderItE5flushEv _ZN5doris10ForEncoderIjE5flushEv Line | Count | Source | 359 | 6 | uint32_t ForEncoder<T>::flush() { | 360 | 6 | if (_buffered_values_num != 0) { | 361 | 0 | bit_packing_one_frame_value(_buffered_values); | 362 | 0 | } | 363 | | | 364 | | // write the footer: | 365 | | // 1 _storage_formats and bit_widths | 366 | 6 | DCHECK(_storage_formats.size() == _bit_widths.size()) | 367 | 0 | << "Size of _storage_formats and _bit_widths should be equal."; | 368 | 18 | for (size_t i = 0; i < _storage_formats.size(); i++) { | 369 | 12 | _buffer->append(&_storage_formats[i], 1); | 370 | 12 | _buffer->append(&_bit_widths[i], 1); | 371 | 12 | } | 372 | | // 2 frame_value_num and values_num | 373 | 6 | uint8_t frame_value_num = FRAME_VALUE_NUM; | 374 | 6 | _buffer->append(&frame_value_num, 1); | 375 | 6 | put_fixed32_le(_buffer, _values_num); | 376 | | | 377 | 6 | return cast_set<uint32_t>(_buffer->size()); | 378 | 6 | } |
Unexecuted instantiation: _ZN5doris10ForEncoderImE5flushEv Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE5flushEv Unexecuted instantiation: _ZN5doris10ForEncoderIoE5flushEv |
379 | | |
380 | | template <typename T> |
381 | 97.8k | const T ForEncoder<T>::numeric_limits_max() { |
382 | 97.8k | return std::numeric_limits<T>::max(); |
383 | 97.8k | } Unexecuted instantiation: _ZN5doris10ForEncoderIaE18numeric_limits_maxEv Unexecuted instantiation: _ZN5doris10ForEncoderIsE18numeric_limits_maxEv _ZN5doris10ForEncoderIiE18numeric_limits_maxEv Line | Count | Source | 381 | 18 | const T ForEncoder<T>::numeric_limits_max() { | 382 | 18 | return std::numeric_limits<T>::max(); | 383 | 18 | } |
_ZN5doris10ForEncoderIlE18numeric_limits_maxEv Line | Count | Source | 381 | 48.9k | const T ForEncoder<T>::numeric_limits_max() { | 382 | 48.9k | return std::numeric_limits<T>::max(); | 383 | 48.9k | } |
_ZN5doris10ForEncoderInE18numeric_limits_maxEv Line | Count | Source | 381 | 48.8k | const T ForEncoder<T>::numeric_limits_max() { | 382 | 48.8k | return std::numeric_limits<T>::max(); | 383 | 48.8k | } |
Unexecuted instantiation: _ZN5doris10ForEncoderIhE18numeric_limits_maxEv Unexecuted instantiation: _ZN5doris10ForEncoderItE18numeric_limits_maxEv _ZN5doris10ForEncoderIjE18numeric_limits_maxEv Line | Count | Source | 381 | 12 | const T ForEncoder<T>::numeric_limits_max() { | 382 | 12 | return std::numeric_limits<T>::max(); | 383 | 12 | } |
Unexecuted instantiation: _ZN5doris10ForEncoderImE18numeric_limits_maxEv Unexecuted instantiation: _ZN5doris10ForEncoderIoE18numeric_limits_maxEv |
384 | | |
385 | | template <> |
386 | 0 | const uint24_t ForEncoder<uint24_t>::numeric_limits_max() { |
387 | 0 | return 0XFFFFFF; |
388 | 0 | } |
389 | | |
390 | | template <typename T> |
391 | 65.3k | bool ForDecoder<T>::init() { |
392 | | // When row count is zero, the minimum footer size is 5: |
393 | | // only has ValuesNum(4) + FrameValueNum(1) |
394 | 65.3k | if (_buffer_len < 5) { |
395 | 0 | return false; |
396 | 0 | } |
397 | | |
398 | 65.3k | _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5); |
399 | 65.3k | _values_num = decode_fixed32_le(_buffer + _buffer_len - 4); |
400 | 65.3k | _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0); |
401 | 65.3k | _last_frame_size = |
402 | 65.3k | cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num)); |
403 | | |
404 | 65.3k | size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2; |
405 | | |
406 | | // read _storage_formats, bit_widths and compute frame_offsets |
407 | 65.3k | u_int32_t frame_start_offset = 0; |
408 | 163k | for (uint32_t i = 0; i < _frame_count; i++) { |
409 | 97.8k | uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset); |
410 | 97.8k | uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1); |
411 | 97.8k | _bit_widths.push_back(bit_width); |
412 | 97.8k | _storage_formats.push_back(order_flag); |
413 | | |
414 | 97.8k | bit_width_offset += 2; |
415 | | |
416 | 97.8k | _frame_offsets.push_back(frame_start_offset); |
417 | 97.8k | if (sizeof(T) == 16) { |
418 | 48.8k | frame_start_offset += bit_width * _max_frame_size / 8 + 16; |
419 | 48.9k | } else if (sizeof(T) == 8) { |
420 | 48.9k | frame_start_offset += bit_width * _max_frame_size / 8 + 8; |
421 | 48.9k | } else { |
422 | 30 | frame_start_offset += bit_width * _max_frame_size / 8 + 4; |
423 | 30 | } |
424 | 97.8k | } |
425 | | |
426 | 65.3k | _out_buffer.resize(_max_frame_size); |
427 | 65.3k | _parsed = true; |
428 | | |
429 | 65.3k | return true; |
430 | 65.3k | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE4initEv Unexecuted instantiation: _ZN5doris10ForDecoderIsE4initEv _ZN5doris10ForDecoderIiE4initEv Line | Count | Source | 391 | 14 | bool ForDecoder<T>::init() { | 392 | | // When row count is zero, the minimum footer size is 5: | 393 | | // only has ValuesNum(4) + FrameValueNum(1) | 394 | 14 | if (_buffer_len < 5) { | 395 | 0 | return false; | 396 | 0 | } | 397 | | | 398 | 14 | _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5); | 399 | 14 | _values_num = decode_fixed32_le(_buffer + _buffer_len - 4); | 400 | 14 | _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0); | 401 | 14 | _last_frame_size = | 402 | 14 | cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num)); | 403 | | | 404 | 14 | size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2; | 405 | | | 406 | | // read _storage_formats, bit_widths and compute frame_offsets | 407 | 14 | u_int32_t frame_start_offset = 0; | 408 | 32 | for (uint32_t i = 0; i < _frame_count; i++) { | 409 | 18 | uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset); | 410 | 18 | uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1); | 411 | 18 | _bit_widths.push_back(bit_width); | 412 | 18 | _storage_formats.push_back(order_flag); | 413 | | | 414 | 18 | bit_width_offset += 2; | 415 | | | 416 | 18 | _frame_offsets.push_back(frame_start_offset); | 417 | 18 | if (sizeof(T) == 16) { | 418 | 0 | frame_start_offset += bit_width * _max_frame_size / 8 + 16; | 419 | 18 | } else if (sizeof(T) == 8) { | 420 | 0 | frame_start_offset += bit_width * _max_frame_size / 8 + 8; | 421 | 18 | } else { | 422 | 18 | frame_start_offset += bit_width * _max_frame_size / 8 + 4; | 423 | 18 | } | 424 | 18 | } | 425 | | | 426 | 14 | _out_buffer.resize(_max_frame_size); | 427 | 14 | _parsed = true; | 428 | | | 429 | 14 | return true; | 430 | 14 | } |
_ZN5doris10ForDecoderIlE4initEv Line | Count | Source | 391 | 32.6k | bool ForDecoder<T>::init() { | 392 | | // When row count is zero, the minimum footer size is 5: | 393 | | // only has ValuesNum(4) + FrameValueNum(1) | 394 | 32.6k | if (_buffer_len < 5) { | 395 | 0 | return false; | 396 | 0 | } | 397 | | | 398 | 32.6k | _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5); | 399 | 32.6k | _values_num = decode_fixed32_le(_buffer + _buffer_len - 4); | 400 | 32.6k | _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0); | 401 | 32.6k | _last_frame_size = | 402 | 32.6k | cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num)); | 403 | | | 404 | 32.6k | size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2; | 405 | | | 406 | | // read _storage_formats, bit_widths and compute frame_offsets | 407 | 32.6k | u_int32_t frame_start_offset = 0; | 408 | 81.5k | for (uint32_t i = 0; i < _frame_count; i++) { | 409 | 48.9k | uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset); | 410 | 48.9k | uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1); | 411 | 48.9k | _bit_widths.push_back(bit_width); | 412 | 48.9k | _storage_formats.push_back(order_flag); | 413 | | | 414 | 48.9k | bit_width_offset += 2; | 415 | | | 416 | 48.9k | _frame_offsets.push_back(frame_start_offset); | 417 | 48.9k | if (sizeof(T) == 16) { | 418 | 0 | frame_start_offset += bit_width * _max_frame_size / 8 + 16; | 419 | 48.9k | } else if (sizeof(T) == 8) { | 420 | 48.9k | frame_start_offset += bit_width * _max_frame_size / 8 + 8; | 421 | 48.9k | } else { | 422 | 0 | frame_start_offset += bit_width * _max_frame_size / 8 + 4; | 423 | 0 | } | 424 | 48.9k | } | 425 | | | 426 | 32.6k | _out_buffer.resize(_max_frame_size); | 427 | 32.6k | _parsed = true; | 428 | | | 429 | 32.6k | return true; | 430 | 32.6k | } |
_ZN5doris10ForDecoderInE4initEv Line | Count | Source | 391 | 32.6k | bool ForDecoder<T>::init() { | 392 | | // When row count is zero, the minimum footer size is 5: | 393 | | // only has ValuesNum(4) + FrameValueNum(1) | 394 | 32.6k | if (_buffer_len < 5) { | 395 | 0 | return false; | 396 | 0 | } | 397 | | | 398 | 32.6k | _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5); | 399 | 32.6k | _values_num = decode_fixed32_le(_buffer + _buffer_len - 4); | 400 | 32.6k | _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0); | 401 | 32.6k | _last_frame_size = | 402 | 32.6k | cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num)); | 403 | | | 404 | 32.6k | size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2; | 405 | | | 406 | | // read _storage_formats, bit_widths and compute frame_offsets | 407 | 32.6k | u_int32_t frame_start_offset = 0; | 408 | 81.5k | for (uint32_t i = 0; i < _frame_count; i++) { | 409 | 48.8k | uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset); | 410 | 48.8k | uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1); | 411 | 48.8k | _bit_widths.push_back(bit_width); | 412 | 48.8k | _storage_formats.push_back(order_flag); | 413 | | | 414 | 48.8k | bit_width_offset += 2; | 415 | | | 416 | 48.8k | _frame_offsets.push_back(frame_start_offset); | 417 | 48.8k | if (sizeof(T) == 16) { | 418 | 48.8k | frame_start_offset += bit_width * _max_frame_size / 8 + 16; | 419 | 48.8k | } else if (sizeof(T) == 8) { | 420 | 0 | frame_start_offset += bit_width * _max_frame_size / 8 + 8; | 421 | 0 | } else { | 422 | 0 | frame_start_offset += bit_width * _max_frame_size / 8 + 4; | 423 | 0 | } | 424 | 48.8k | } | 425 | | | 426 | 32.6k | _out_buffer.resize(_max_frame_size); | 427 | 32.6k | _parsed = true; | 428 | | | 429 | 32.6k | return true; | 430 | 32.6k | } |
Unexecuted instantiation: _ZN5doris10ForDecoderIhE4initEv Unexecuted instantiation: _ZN5doris10ForDecoderItE4initEv _ZN5doris10ForDecoderIjE4initEv Line | Count | Source | 391 | 6 | bool ForDecoder<T>::init() { | 392 | | // When row count is zero, the minimum footer size is 5: | 393 | | // only has ValuesNum(4) + FrameValueNum(1) | 394 | 6 | if (_buffer_len < 5) { | 395 | 0 | return false; | 396 | 0 | } | 397 | | | 398 | 6 | _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5); | 399 | 6 | _values_num = decode_fixed32_le(_buffer + _buffer_len - 4); | 400 | 6 | _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0); | 401 | 6 | _last_frame_size = | 402 | 6 | cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num)); | 403 | | | 404 | 6 | size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2; | 405 | | | 406 | | // read _storage_formats, bit_widths and compute frame_offsets | 407 | 6 | u_int32_t frame_start_offset = 0; | 408 | 18 | for (uint32_t i = 0; i < _frame_count; i++) { | 409 | 12 | uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset); | 410 | 12 | uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1); | 411 | 12 | _bit_widths.push_back(bit_width); | 412 | 12 | _storage_formats.push_back(order_flag); | 413 | | | 414 | 12 | bit_width_offset += 2; | 415 | | | 416 | 12 | _frame_offsets.push_back(frame_start_offset); | 417 | 12 | if (sizeof(T) == 16) { | 418 | 0 | frame_start_offset += bit_width * _max_frame_size / 8 + 16; | 419 | 12 | } else if (sizeof(T) == 8) { | 420 | 0 | frame_start_offset += bit_width * _max_frame_size / 8 + 8; | 421 | 12 | } else { | 422 | 12 | frame_start_offset += bit_width * _max_frame_size / 8 + 4; | 423 | 12 | } | 424 | 12 | } | 425 | | | 426 | 6 | _out_buffer.resize(_max_frame_size); | 427 | 6 | _parsed = true; | 428 | | | 429 | 6 | return true; | 430 | 6 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderImE4initEv Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE4initEv Unexecuted instantiation: _ZN5doris10ForDecoderIoE4initEv |
431 | | |
432 | | // todo(kks): improve this method by SIMD instructions |
433 | | |
434 | | template <typename T> |
435 | | template <typename U> |
436 | | void ForDecoder<T>::bit_unpack_optimize(const uint8_t* input, uint8_t in_num, int bit_width, |
437 | 162k | T* output) { |
438 | 162k | static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value, |
439 | 162k | "bit_unpack_optimize only supports U = int64_t or __int128_t"); |
440 | 162k | constexpr int u_size = sizeof(U); // Size of U |
441 | 162k | constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size) |
442 | 162k | int valid_bit = 0; // How many valid bits |
443 | 162k | int need_bit = 0; // still need |
444 | 162k | size_t input_size = (in_num * bit_width + 7) >> 3; // input's size |
445 | 162k | int full_batch_size = |
446 | 162k | cast_set<int>((input_size >> u_size_shift) |
447 | 162k | << u_size_shift); // Adjust input_size to a multiple of u_size |
448 | 162k | int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size. |
449 | | // The number of bits in input to adjust to multiples of 8 and thus more |
450 | 162k | int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width)); |
451 | | |
452 | | // to ensure that only bit_width bits are valid |
453 | 162k | T output_mask; |
454 | 162k | if (bit_width >= static_cast<int>(sizeof(T) * 8)) { |
455 | 0 | output_mask = static_cast<T>(~T(0)); |
456 | 162k | } else { |
457 | 162k | output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1); |
458 | 162k | } |
459 | | |
460 | 162k | U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking |
461 | | |
462 | 8.96M | for (int i = 0; i < full_batch_size; i += u_size) { |
463 | 8.80M | s = 0; |
464 | | |
465 | 8.80M | s = to_endian<std::endian::big>(*((U*)(input + i))); |
466 | | |
467 | | // Determine what the valid bits are based on u_size |
468 | 8.80M | valid_bit = u_size << 3; |
469 | | |
470 | | // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop. |
471 | 8.80M | if (tail_count == 0 && i == full_batch_size - u_size) { |
472 | 43.5k | valid_bit -= more_bit; |
473 | 43.5k | s >>= more_bit; |
474 | 43.5k | } |
475 | | |
476 | 8.80M | if (need_bit) { |
477 | | // The last time we take away the high bit_width - need_bit, |
478 | | // we need to make up the rest of the need_bit from the width. |
479 | | // Use valid_bit - need_bit to compute high need_bit bits of s |
480 | | // perform an AND operation to ensure that only need_bit bits are valid |
481 | 8.18M | auto mask = (static_cast<U>(1) << need_bit) - 1; |
482 | 8.18M | auto shifted = s >> (valid_bit - need_bit); |
483 | 8.18M | auto masked_result = shifted & mask; |
484 | 8.18M | if constexpr (sizeof(T) <= 4) { |
485 | 0 | *output |= static_cast<T>(static_cast<uint32_t>(masked_result)); |
486 | 8.18M | } else { |
487 | 8.18M | *output |= static_cast<T>(masked_result); |
488 | 8.18M | } |
489 | 8.18M | output++; |
490 | 8.18M | valid_bit -= need_bit; |
491 | 8.18M | } |
492 | | |
493 | 8.80M | int num = valid_bit / bit_width; // How many outputs can be processed at a time |
494 | 8.80M | int remainder = valid_bit - num * bit_width; // How many bits are left to store |
495 | | |
496 | | // Starting with the highest valid bit, take out bit_width bits in sequence |
497 | | // perform an AND operation with output_mask to ensure that only bit_width bits are valid |
498 | | // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end |
499 | | // But since there are still remainder bits that can't be processed, need to add the remainder |
500 | 17.0M | for (int j = 0; j < num; j++) { |
501 | 8.22M | *output = |
502 | 8.22M | static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask); |
503 | 8.22M | output++; |
504 | 8.22M | } |
505 | | |
506 | 8.80M | if (remainder) { |
507 | | // Process the last remaining remainder bit. |
508 | | // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits. |
509 | | // output = y << (bit_width - remainder) Use the high bit_width - remainder bit |
510 | 8.28M | if constexpr (sizeof(T) <= 4) { |
511 | 0 | auto masked_value = static_cast<T>( |
512 | 0 | static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1))); |
513 | 0 | *output = static_cast<T>(masked_value << (bit_width - remainder)); |
514 | 8.28M | } else { |
515 | 8.28M | auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1))); |
516 | 8.28M | *output = static_cast<T>(masked_value << (bit_width - remainder)); |
517 | 8.28M | } |
518 | | // Already have remainder bits, next time need bit_width - remainder bits |
519 | 8.28M | need_bit = bit_width - remainder; |
520 | 8.28M | } else { |
521 | 515k | need_bit = 0; |
522 | 515k | } |
523 | 8.80M | } |
524 | | |
525 | | // remainder |
526 | 162k | if (tail_count) { |
527 | | // Put the tail_count numbers in the input into s in order, each number occupies 8 bit |
528 | 954k | for (int i = 0; i < tail_count; i++) { |
529 | 835k | s <<= 8; |
530 | 835k | s |= input[full_batch_size + i]; |
531 | 835k | } |
532 | | |
533 | | // tail * 8 is the number of bits that are left to process |
534 | | // tail * 8 - more_bit is to remove the last more_bit |
535 | 118k | valid_bit = (tail_count << 3) - more_bit; |
536 | 118k | s >>= more_bit; |
537 | | |
538 | | // same as before |
539 | 118k | if (need_bit) { |
540 | 108k | if constexpr (sizeof(T) <= 4) { |
541 | 0 | *output |= static_cast<T>(static_cast<uint32_t>( |
542 | 0 | (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1))); |
543 | 108k | } else { |
544 | 108k | *output |= static_cast<T>((s >> (valid_bit - need_bit)) & |
545 | 108k | ((static_cast<U>(1) << need_bit) - 1)); |
546 | 108k | } |
547 | 108k | output++; |
548 | 108k | valid_bit -= need_bit; |
549 | 108k | } |
550 | | |
551 | 118k | int num = valid_bit / bit_width; // How many outputs can be processed at a time |
552 | | |
553 | | // same as before |
554 | 253k | for (int j = 0; j < num; j++) { |
555 | 134k | *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask); |
556 | 134k | output++; |
557 | 134k | } |
558 | 118k | } |
559 | 162k | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE19bit_unpack_optimizeIlEEvPKhhiPa Unexecuted instantiation: _ZN5doris10ForDecoderIaE19bit_unpack_optimizeInEEvPKhhiPa Unexecuted instantiation: _ZN5doris10ForDecoderIsE19bit_unpack_optimizeIlEEvPKhhiPs Unexecuted instantiation: _ZN5doris10ForDecoderIsE19bit_unpack_optimizeInEEvPKhhiPs _ZN5doris10ForDecoderIiE19bit_unpack_optimizeIlEEvPKhhiPi Line | Count | Source | 437 | 18 | T* output) { | 438 | 18 | static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value, | 439 | 18 | "bit_unpack_optimize only supports U = int64_t or __int128_t"); | 440 | 18 | constexpr int u_size = sizeof(U); // Size of U | 441 | 18 | constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size) | 442 | 18 | int valid_bit = 0; // How many valid bits | 443 | 18 | int need_bit = 0; // still need | 444 | 18 | size_t input_size = (in_num * bit_width + 7) >> 3; // input's size | 445 | 18 | int full_batch_size = | 446 | 18 | cast_set<int>((input_size >> u_size_shift) | 447 | 18 | << u_size_shift); // Adjust input_size to a multiple of u_size | 448 | 18 | int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size. | 449 | | // The number of bits in input to adjust to multiples of 8 and thus more | 450 | 18 | int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width)); | 451 | | | 452 | | // to ensure that only bit_width bits are valid | 453 | 18 | T output_mask; | 454 | 18 | if (bit_width >= static_cast<int>(sizeof(T) * 8)) { | 455 | 0 | output_mask = static_cast<T>(~T(0)); | 456 | 18 | } else { | 457 | 18 | output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1); | 458 | 18 | } | 459 | | | 460 | 18 | U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking | 461 | | | 462 | 42 | for (int i = 0; i < full_batch_size; i += u_size) { | 463 | 24 | s = 0; | 464 | | | 465 | 24 | s = to_endian<std::endian::big>(*((U*)(input + i))); | 466 | | | 467 | | // Determine what the valid bits are based on u_size | 468 | 24 | valid_bit = u_size << 3; | 469 | | | 470 | | // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop. | 471 | 24 | if (tail_count == 0 && i == full_batch_size - u_size) { | 472 | 14 | valid_bit -= more_bit; | 473 | 14 | s >>= more_bit; | 474 | 14 | } | 475 | | | 476 | 24 | if (need_bit) { | 477 | | // The last time we take away the high bit_width - need_bit, | 478 | | // we need to make up the rest of the need_bit from the width. | 479 | | // Use valid_bit - need_bit to compute high need_bit bits of s | 480 | | // perform an AND operation to ensure that only need_bit bits are valid | 481 | 0 | auto mask = (static_cast<U>(1) << need_bit) - 1; | 482 | 0 | auto shifted = s >> (valid_bit - need_bit); | 483 | 0 | auto masked_result = shifted & mask; | 484 | 0 | if constexpr (sizeof(T) <= 4) { | 485 | 0 | *output |= static_cast<T>(static_cast<uint32_t>(masked_result)); | 486 | | } else { | 487 | | *output |= static_cast<T>(masked_result); | 488 | | } | 489 | 0 | output++; | 490 | 0 | valid_bit -= need_bit; | 491 | 0 | } | 492 | | | 493 | 24 | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 494 | 24 | int remainder = valid_bit - num * bit_width; // How many bits are left to store | 495 | | | 496 | | // Starting with the highest valid bit, take out bit_width bits in sequence | 497 | | // perform an AND operation with output_mask to ensure that only bit_width bits are valid | 498 | | // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end | 499 | | // But since there are still remainder bits that can't be processed, need to add the remainder | 500 | 1.56k | for (int j = 0; j < num; j++) { | 501 | 1.53k | *output = | 502 | 1.53k | static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask); | 503 | 1.53k | output++; | 504 | 1.53k | } | 505 | | | 506 | 24 | if (remainder) { | 507 | | // Process the last remaining remainder bit. | 508 | | // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits. | 509 | | // output = y << (bit_width - remainder) Use the high bit_width - remainder bit | 510 | 0 | if constexpr (sizeof(T) <= 4) { | 511 | 0 | auto masked_value = static_cast<T>( | 512 | 0 | static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1))); | 513 | 0 | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 514 | | } else { | 515 | | auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1))); | 516 | | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 517 | | } | 518 | | // Already have remainder bits, next time need bit_width - remainder bits | 519 | 0 | need_bit = bit_width - remainder; | 520 | 24 | } else { | 521 | 24 | need_bit = 0; | 522 | 24 | } | 523 | 24 | } | 524 | | | 525 | | // remainder | 526 | 18 | if (tail_count) { | 527 | | // Put the tail_count numbers in the input into s in order, each number occupies 8 bit | 528 | 4 | for (int i = 0; i < tail_count; i++) { | 529 | 2 | s <<= 8; | 530 | 2 | s |= input[full_batch_size + i]; | 531 | 2 | } | 532 | | | 533 | | // tail * 8 is the number of bits that are left to process | 534 | | // tail * 8 - more_bit is to remove the last more_bit | 535 | 2 | valid_bit = (tail_count << 3) - more_bit; | 536 | 2 | s >>= more_bit; | 537 | | | 538 | | // same as before | 539 | 2 | if (need_bit) { | 540 | 0 | if constexpr (sizeof(T) <= 4) { | 541 | 0 | *output |= static_cast<T>(static_cast<uint32_t>( | 542 | 0 | (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1))); | 543 | | } else { | 544 | | *output |= static_cast<T>((s >> (valid_bit - need_bit)) & | 545 | | ((static_cast<U>(1) << need_bit) - 1)); | 546 | | } | 547 | 0 | output++; | 548 | 0 | valid_bit -= need_bit; | 549 | 0 | } | 550 | | | 551 | 2 | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 552 | | | 553 | | // same as before | 554 | 6 | for (int j = 0; j < num; j++) { | 555 | 4 | *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask); | 556 | 4 | output++; | 557 | 4 | } | 558 | 2 | } | 559 | 18 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderIiE19bit_unpack_optimizeInEEvPKhhiPi _ZN5doris10ForDecoderIlE19bit_unpack_optimizeIlEEvPKhhiPl Line | Count | Source | 437 | 24.6k | T* output) { | 438 | 24.6k | static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value, | 439 | 24.6k | "bit_unpack_optimize only supports U = int64_t or __int128_t"); | 440 | 24.6k | constexpr int u_size = sizeof(U); // Size of U | 441 | 24.6k | constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size) | 442 | 24.6k | int valid_bit = 0; // How many valid bits | 443 | 24.6k | int need_bit = 0; // still need | 444 | 24.6k | size_t input_size = (in_num * bit_width + 7) >> 3; // input's size | 445 | 24.6k | int full_batch_size = | 446 | 24.6k | cast_set<int>((input_size >> u_size_shift) | 447 | 24.6k | << u_size_shift); // Adjust input_size to a multiple of u_size | 448 | 24.6k | int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size. | 449 | | // The number of bits in input to adjust to multiples of 8 and thus more | 450 | 24.6k | int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width)); | 451 | | | 452 | | // to ensure that only bit_width bits are valid | 453 | 24.6k | T output_mask; | 454 | 24.6k | if (bit_width >= static_cast<int>(sizeof(T) * 8)) { | 455 | 0 | output_mask = static_cast<T>(~T(0)); | 456 | 24.6k | } else { | 457 | 24.6k | output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1); | 458 | 24.6k | } | 459 | | | 460 | 24.6k | U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking | 461 | | | 462 | 556k | for (int i = 0; i < full_batch_size; i += u_size) { | 463 | 532k | s = 0; | 464 | | | 465 | 532k | s = to_endian<std::endian::big>(*((U*)(input + i))); | 466 | | | 467 | | // Determine what the valid bits are based on u_size | 468 | 532k | valid_bit = u_size << 3; | 469 | | | 470 | | // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop. | 471 | 532k | if (tail_count == 0 && i == full_batch_size - u_size) { | 472 | 10.3k | valid_bit -= more_bit; | 473 | 10.3k | s >>= more_bit; | 474 | 10.3k | } | 475 | | | 476 | 532k | if (need_bit) { | 477 | | // The last time we take away the high bit_width - need_bit, | 478 | | // we need to make up the rest of the need_bit from the width. | 479 | | // Use valid_bit - need_bit to compute high need_bit bits of s | 480 | | // perform an AND operation to ensure that only need_bit bits are valid | 481 | 414k | auto mask = (static_cast<U>(1) << need_bit) - 1; | 482 | 414k | auto shifted = s >> (valid_bit - need_bit); | 483 | 414k | auto masked_result = shifted & mask; | 484 | | if constexpr (sizeof(T) <= 4) { | 485 | | *output |= static_cast<T>(static_cast<uint32_t>(masked_result)); | 486 | 414k | } else { | 487 | 414k | *output |= static_cast<T>(masked_result); | 488 | 414k | } | 489 | 414k | output++; | 490 | 414k | valid_bit -= need_bit; | 491 | 414k | } | 492 | | | 493 | 532k | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 494 | 532k | int remainder = valid_bit - num * bit_width; // How many bits are left to store | 495 | | | 496 | | // Starting with the highest valid bit, take out bit_width bits in sequence | 497 | | // perform an AND operation with output_mask to ensure that only bit_width bits are valid | 498 | | // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end | 499 | | // But since there are still remainder bits that can't be processed, need to add the remainder | 500 | 2.15M | for (int j = 0; j < num; j++) { | 501 | 1.61M | *output = | 502 | 1.61M | static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask); | 503 | 1.61M | output++; | 504 | 1.61M | } | 505 | | | 506 | 532k | if (remainder) { | 507 | | // Process the last remaining remainder bit. | 508 | | // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits. | 509 | | // output = y << (bit_width - remainder) Use the high bit_width - remainder bit | 510 | | if constexpr (sizeof(T) <= 4) { | 511 | | auto masked_value = static_cast<T>( | 512 | | static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1))); | 513 | | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 514 | 424k | } else { | 515 | 424k | auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1))); | 516 | 424k | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 517 | 424k | } | 518 | | // Already have remainder bits, next time need bit_width - remainder bits | 519 | 424k | need_bit = bit_width - remainder; | 520 | 424k | } else { | 521 | 107k | need_bit = 0; | 522 | 107k | } | 523 | 532k | } | 524 | | | 525 | | // remainder | 526 | 24.6k | if (tail_count) { | 527 | | // Put the tail_count numbers in the input into s in order, each number occupies 8 bit | 528 | 70.0k | for (int i = 0; i < tail_count; i++) { | 529 | 56.0k | s <<= 8; | 530 | 56.0k | s |= input[full_batch_size + i]; | 531 | 56.0k | } | 532 | | | 533 | | // tail * 8 is the number of bits that are left to process | 534 | | // tail * 8 - more_bit is to remove the last more_bit | 535 | 13.9k | valid_bit = (tail_count << 3) - more_bit; | 536 | 13.9k | s >>= more_bit; | 537 | | | 538 | | // same as before | 539 | 13.9k | if (need_bit) { | 540 | | if constexpr (sizeof(T) <= 4) { | 541 | | *output |= static_cast<T>(static_cast<uint32_t>( | 542 | | (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1))); | 543 | 10.2k | } else { | 544 | 10.2k | *output |= static_cast<T>((s >> (valid_bit - need_bit)) & | 545 | 10.2k | ((static_cast<U>(1) << need_bit) - 1)); | 546 | 10.2k | } | 547 | 10.2k | output++; | 548 | 10.2k | valid_bit -= need_bit; | 549 | 10.2k | } | 550 | | | 551 | 13.9k | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 552 | | | 553 | | // same as before | 554 | 61.3k | for (int j = 0; j < num; j++) { | 555 | 47.3k | *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask); | 556 | 47.3k | output++; | 557 | 47.3k | } | 558 | 13.9k | } | 559 | 24.6k | } |
_ZN5doris10ForDecoderIlE19bit_unpack_optimizeInEEvPKhhiPl Line | Count | Source | 437 | 24.3k | T* output) { | 438 | 24.3k | static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value, | 439 | 24.3k | "bit_unpack_optimize only supports U = int64_t or __int128_t"); | 440 | 24.3k | constexpr int u_size = sizeof(U); // Size of U | 441 | 24.3k | constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size) | 442 | 24.3k | int valid_bit = 0; // How many valid bits | 443 | 24.3k | int need_bit = 0; // still need | 444 | 24.3k | size_t input_size = (in_num * bit_width + 7) >> 3; // input's size | 445 | 24.3k | int full_batch_size = | 446 | 24.3k | cast_set<int>((input_size >> u_size_shift) | 447 | 24.3k | << u_size_shift); // Adjust input_size to a multiple of u_size | 448 | 24.3k | int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size. | 449 | | // The number of bits in input to adjust to multiples of 8 and thus more | 450 | 24.3k | int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width)); | 451 | | | 452 | | // to ensure that only bit_width bits are valid | 453 | 24.3k | T output_mask; | 454 | 24.3k | if (bit_width >= static_cast<int>(sizeof(T) * 8)) { | 455 | 0 | output_mask = static_cast<T>(~T(0)); | 456 | 24.3k | } else { | 457 | 24.3k | output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1); | 458 | 24.3k | } | 459 | | | 460 | 24.3k | U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking | 461 | | | 462 | 807k | for (int i = 0; i < full_batch_size; i += u_size) { | 463 | 783k | s = 0; | 464 | | | 465 | 783k | s = to_endian<std::endian::big>(*((U*)(input + i))); | 466 | | | 467 | | // Determine what the valid bits are based on u_size | 468 | 783k | valid_bit = u_size << 3; | 469 | | | 470 | | // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop. | 471 | 783k | if (tail_count == 0 && i == full_batch_size - u_size) { | 472 | 9.10k | valid_bit -= more_bit; | 473 | 9.10k | s >>= more_bit; | 474 | 9.10k | } | 475 | | | 476 | 783k | if (need_bit) { | 477 | | // The last time we take away the high bit_width - need_bit, | 478 | | // we need to make up the rest of the need_bit from the width. | 479 | | // Use valid_bit - need_bit to compute high need_bit bits of s | 480 | | // perform an AND operation to ensure that only need_bit bits are valid | 481 | 735k | auto mask = (static_cast<U>(1) << need_bit) - 1; | 482 | 735k | auto shifted = s >> (valid_bit - need_bit); | 483 | 735k | auto masked_result = shifted & mask; | 484 | | if constexpr (sizeof(T) <= 4) { | 485 | | *output |= static_cast<T>(static_cast<uint32_t>(masked_result)); | 486 | 735k | } else { | 487 | 735k | *output |= static_cast<T>(masked_result); | 488 | 735k | } | 489 | 735k | output++; | 490 | 735k | valid_bit -= need_bit; | 491 | 735k | } | 492 | | | 493 | 783k | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 494 | 783k | int remainder = valid_bit - num * bit_width; // How many bits are left to store | 495 | | | 496 | | // Starting with the highest valid bit, take out bit_width bits in sequence | 497 | | // perform an AND operation with output_mask to ensure that only bit_width bits are valid | 498 | | // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end | 499 | | // But since there are still remainder bits that can't be processed, need to add the remainder | 500 | 2.10M | for (int j = 0; j < num; j++) { | 501 | 1.32M | *output = | 502 | 1.32M | static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask); | 503 | 1.32M | output++; | 504 | 1.32M | } | 505 | | | 506 | 783k | if (remainder) { | 507 | | // Process the last remaining remainder bit. | 508 | | // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits. | 509 | | // output = y << (bit_width - remainder) Use the high bit_width - remainder bit | 510 | | if constexpr (sizeof(T) <= 4) { | 511 | | auto masked_value = static_cast<T>( | 512 | | static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1))); | 513 | | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 514 | 749k | } else { | 515 | 749k | auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1))); | 516 | 749k | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 517 | 749k | } | 518 | | // Already have remainder bits, next time need bit_width - remainder bits | 519 | 749k | need_bit = bit_width - remainder; | 520 | 749k | } else { | 521 | 33.9k | need_bit = 0; | 522 | 33.9k | } | 523 | 783k | } | 524 | | | 525 | | // remainder | 526 | 24.3k | if (tail_count) { | 527 | | // Put the tail_count numbers in the input into s in order, each number occupies 8 bit | 528 | 137k | for (int i = 0; i < tail_count; i++) { | 529 | 121k | s <<= 8; | 530 | 121k | s |= input[full_batch_size + i]; | 531 | 121k | } | 532 | | | 533 | | // tail * 8 is the number of bits that are left to process | 534 | | // tail * 8 - more_bit is to remove the last more_bit | 535 | 15.2k | valid_bit = (tail_count << 3) - more_bit; | 536 | 15.2k | s >>= more_bit; | 537 | | | 538 | | // same as before | 539 | 15.2k | if (need_bit) { | 540 | | if constexpr (sizeof(T) <= 4) { | 541 | | *output |= static_cast<T>(static_cast<uint32_t>( | 542 | | (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1))); | 543 | 14.6k | } else { | 544 | 14.6k | *output |= static_cast<T>((s >> (valid_bit - need_bit)) & | 545 | 14.6k | ((static_cast<U>(1) << need_bit) - 1)); | 546 | 14.6k | } | 547 | 14.6k | output++; | 548 | 14.6k | valid_bit -= need_bit; | 549 | 14.6k | } | 550 | | | 551 | 15.2k | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 552 | | | 553 | | // same as before | 554 | 28.2k | for (int j = 0; j < num; j++) { | 555 | 13.0k | *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask); | 556 | 13.0k | output++; | 557 | 13.0k | } | 558 | 15.2k | } | 559 | 24.3k | } |
_ZN5doris10ForDecoderInE19bit_unpack_optimizeIlEEvPKhhiPn Line | Count | Source | 437 | 16.5k | T* output) { | 438 | 16.5k | static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value, | 439 | 16.5k | "bit_unpack_optimize only supports U = int64_t or __int128_t"); | 440 | 16.5k | constexpr int u_size = sizeof(U); // Size of U | 441 | 16.5k | constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size) | 442 | 16.5k | int valid_bit = 0; // How many valid bits | 443 | 16.5k | int need_bit = 0; // still need | 444 | 16.5k | size_t input_size = (in_num * bit_width + 7) >> 3; // input's size | 445 | 16.5k | int full_batch_size = | 446 | 16.5k | cast_set<int>((input_size >> u_size_shift) | 447 | 16.5k | << u_size_shift); // Adjust input_size to a multiple of u_size | 448 | 16.5k | int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size. | 449 | | // The number of bits in input to adjust to multiples of 8 and thus more | 450 | 16.5k | int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width)); | 451 | | | 452 | | // to ensure that only bit_width bits are valid | 453 | 16.5k | T output_mask; | 454 | 16.5k | if (bit_width >= static_cast<int>(sizeof(T) * 8)) { | 455 | 0 | output_mask = static_cast<T>(~T(0)); | 456 | 16.5k | } else { | 457 | 16.5k | output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1); | 458 | 16.5k | } | 459 | | | 460 | 16.5k | U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking | 461 | | | 462 | 548k | for (int i = 0; i < full_batch_size; i += u_size) { | 463 | 532k | s = 0; | 464 | | | 465 | 532k | s = to_endian<std::endian::big>(*((U*)(input + i))); | 466 | | | 467 | | // Determine what the valid bits are based on u_size | 468 | 532k | valid_bit = u_size << 3; | 469 | | | 470 | | // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop. | 471 | 532k | if (tail_count == 0 && i == full_batch_size - u_size) { | 472 | 2.24k | valid_bit -= more_bit; | 473 | 2.24k | s >>= more_bit; | 474 | 2.24k | } | 475 | | | 476 | 532k | if (need_bit) { | 477 | | // The last time we take away the high bit_width - need_bit, | 478 | | // we need to make up the rest of the need_bit from the width. | 479 | | // Use valid_bit - need_bit to compute high need_bit bits of s | 480 | | // perform an AND operation to ensure that only need_bit bits are valid | 481 | 414k | auto mask = (static_cast<U>(1) << need_bit) - 1; | 482 | 414k | auto shifted = s >> (valid_bit - need_bit); | 483 | 414k | auto masked_result = shifted & mask; | 484 | | if constexpr (sizeof(T) <= 4) { | 485 | | *output |= static_cast<T>(static_cast<uint32_t>(masked_result)); | 486 | 414k | } else { | 487 | 414k | *output |= static_cast<T>(masked_result); | 488 | 414k | } | 489 | 414k | output++; | 490 | 414k | valid_bit -= need_bit; | 491 | 414k | } | 492 | | | 493 | 532k | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 494 | 532k | int remainder = valid_bit - num * bit_width; // How many bits are left to store | 495 | | | 496 | | // Starting with the highest valid bit, take out bit_width bits in sequence | 497 | | // perform an AND operation with output_mask to ensure that only bit_width bits are valid | 498 | | // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end | 499 | | // But since there are still remainder bits that can't be processed, need to add the remainder | 500 | 2.14M | for (int j = 0; j < num; j++) { | 501 | 1.61M | *output = | 502 | 1.61M | static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask); | 503 | 1.61M | output++; | 504 | 1.61M | } | 505 | | | 506 | 532k | if (remainder) { | 507 | | // Process the last remaining remainder bit. | 508 | | // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits. | 509 | | // output = y << (bit_width - remainder) Use the high bit_width - remainder bit | 510 | | if constexpr (sizeof(T) <= 4) { | 511 | | auto masked_value = static_cast<T>( | 512 | | static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1))); | 513 | | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 514 | 424k | } else { | 515 | 424k | auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1))); | 516 | 424k | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 517 | 424k | } | 518 | | // Already have remainder bits, next time need bit_width - remainder bits | 519 | 424k | need_bit = bit_width - remainder; | 520 | 424k | } else { | 521 | 107k | need_bit = 0; | 522 | 107k | } | 523 | 532k | } | 524 | | | 525 | | // remainder | 526 | 16.5k | if (tail_count) { | 527 | | // Put the tail_count numbers in the input into s in order, each number occupies 8 bit | 528 | 70.4k | for (int i = 0; i < tail_count; i++) { | 529 | 56.3k | s <<= 8; | 530 | 56.3k | s |= input[full_batch_size + i]; | 531 | 56.3k | } | 532 | | | 533 | | // tail * 8 is the number of bits that are left to process | 534 | | // tail * 8 - more_bit is to remove the last more_bit | 535 | 14.0k | valid_bit = (tail_count << 3) - more_bit; | 536 | 14.0k | s >>= more_bit; | 537 | | | 538 | | // same as before | 539 | 14.0k | if (need_bit) { | 540 | | if constexpr (sizeof(T) <= 4) { | 541 | | *output |= static_cast<T>(static_cast<uint32_t>( | 542 | | (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1))); | 543 | 10.2k | } else { | 544 | 10.2k | *output |= static_cast<T>((s >> (valid_bit - need_bit)) & | 545 | 10.2k | ((static_cast<U>(1) << need_bit) - 1)); | 546 | 10.2k | } | 547 | 10.2k | output++; | 548 | 10.2k | valid_bit -= need_bit; | 549 | 10.2k | } | 550 | | | 551 | 14.0k | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 552 | | | 553 | | // same as before | 554 | 61.5k | for (int j = 0; j < num; j++) { | 555 | 47.4k | *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask); | 556 | 47.4k | output++; | 557 | 47.4k | } | 558 | 14.0k | } | 559 | 16.5k | } |
_ZN5doris10ForDecoderInE19bit_unpack_optimizeInEEvPKhhiPn Line | Count | Source | 437 | 97.0k | T* output) { | 438 | 97.0k | static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value, | 439 | 97.0k | "bit_unpack_optimize only supports U = int64_t or __int128_t"); | 440 | 97.0k | constexpr int u_size = sizeof(U); // Size of U | 441 | 97.0k | constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size) | 442 | 97.0k | int valid_bit = 0; // How many valid bits | 443 | 97.0k | int need_bit = 0; // still need | 444 | 97.0k | size_t input_size = (in_num * bit_width + 7) >> 3; // input's size | 445 | 97.0k | int full_batch_size = | 446 | 97.0k | cast_set<int>((input_size >> u_size_shift) | 447 | 97.0k | << u_size_shift); // Adjust input_size to a multiple of u_size | 448 | 97.0k | int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size. | 449 | | // The number of bits in input to adjust to multiples of 8 and thus more | 450 | 97.0k | int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width)); | 451 | | | 452 | | // to ensure that only bit_width bits are valid | 453 | 97.0k | T output_mask; | 454 | 97.0k | if (bit_width >= static_cast<int>(sizeof(T) * 8)) { | 455 | 0 | output_mask = static_cast<T>(~T(0)); | 456 | 97.0k | } else { | 457 | 97.0k | output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1); | 458 | 97.0k | } | 459 | | | 460 | 97.0k | U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking | 461 | | | 462 | 7.05M | for (int i = 0; i < full_batch_size; i += u_size) { | 463 | 6.95M | s = 0; | 464 | | | 465 | 6.95M | s = to_endian<std::endian::big>(*((U*)(input + i))); | 466 | | | 467 | | // Determine what the valid bits are based on u_size | 468 | 6.95M | valid_bit = u_size << 3; | 469 | | | 470 | | // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop. | 471 | 6.95M | if (tail_count == 0 && i == full_batch_size - u_size) { | 472 | 21.7k | valid_bit -= more_bit; | 473 | 21.7k | s >>= more_bit; | 474 | 21.7k | } | 475 | | | 476 | 6.95M | if (need_bit) { | 477 | | // The last time we take away the high bit_width - need_bit, | 478 | | // we need to make up the rest of the need_bit from the width. | 479 | | // Use valid_bit - need_bit to compute high need_bit bits of s | 480 | | // perform an AND operation to ensure that only need_bit bits are valid | 481 | 6.61M | auto mask = (static_cast<U>(1) << need_bit) - 1; | 482 | 6.61M | auto shifted = s >> (valid_bit - need_bit); | 483 | 6.61M | auto masked_result = shifted & mask; | 484 | | if constexpr (sizeof(T) <= 4) { | 485 | | *output |= static_cast<T>(static_cast<uint32_t>(masked_result)); | 486 | 6.61M | } else { | 487 | 6.61M | *output |= static_cast<T>(masked_result); | 488 | 6.61M | } | 489 | 6.61M | output++; | 490 | 6.61M | valid_bit -= need_bit; | 491 | 6.61M | } | 492 | | | 493 | 6.95M | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 494 | 6.95M | int remainder = valid_bit - num * bit_width; // How many bits are left to store | 495 | | | 496 | | // Starting with the highest valid bit, take out bit_width bits in sequence | 497 | | // perform an AND operation with output_mask to ensure that only bit_width bits are valid | 498 | | // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end | 499 | | // But since there are still remainder bits that can't be processed, need to add the remainder | 500 | 10.6M | for (int j = 0; j < num; j++) { | 501 | 3.66M | *output = | 502 | 3.66M | static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask); | 503 | 3.66M | output++; | 504 | 3.66M | } | 505 | | | 506 | 6.95M | if (remainder) { | 507 | | // Process the last remaining remainder bit. | 508 | | // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits. | 509 | | // output = y << (bit_width - remainder) Use the high bit_width - remainder bit | 510 | | if constexpr (sizeof(T) <= 4) { | 511 | | auto masked_value = static_cast<T>( | 512 | | static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1))); | 513 | | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 514 | 6.69M | } else { | 515 | 6.69M | auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1))); | 516 | 6.69M | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 517 | 6.69M | } | 518 | | // Already have remainder bits, next time need bit_width - remainder bits | 519 | 6.69M | need_bit = bit_width - remainder; | 520 | 6.69M | } else { | 521 | 265k | need_bit = 0; | 522 | 265k | } | 523 | 6.95M | } | 524 | | | 525 | | // remainder | 526 | 97.0k | if (tail_count) { | 527 | | // Put the tail_count numbers in the input into s in order, each number occupies 8 bit | 528 | 676k | for (int i = 0; i < tail_count; i++) { | 529 | 601k | s <<= 8; | 530 | 601k | s |= input[full_batch_size + i]; | 531 | 601k | } | 532 | | | 533 | | // tail * 8 is the number of bits that are left to process | 534 | | // tail * 8 - more_bit is to remove the last more_bit | 535 | 75.2k | valid_bit = (tail_count << 3) - more_bit; | 536 | 75.2k | s >>= more_bit; | 537 | | | 538 | | // same as before | 539 | 75.2k | if (need_bit) { | 540 | | if constexpr (sizeof(T) <= 4) { | 541 | | *output |= static_cast<T>(static_cast<uint32_t>( | 542 | | (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1))); | 543 | 72.8k | } else { | 544 | 72.8k | *output |= static_cast<T>((s >> (valid_bit - need_bit)) & | 545 | 72.8k | ((static_cast<U>(1) << need_bit) - 1)); | 546 | 72.8k | } | 547 | 72.8k | output++; | 548 | 72.8k | valid_bit -= need_bit; | 549 | 72.8k | } | 550 | | | 551 | 75.2k | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 552 | | | 553 | | // same as before | 554 | 101k | for (int j = 0; j < num; j++) { | 555 | 26.6k | *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask); | 556 | 26.6k | output++; | 557 | 26.6k | } | 558 | 75.2k | } | 559 | 97.0k | } |
Unexecuted instantiation: _ZN5doris10ForDecoderIhE19bit_unpack_optimizeIlEEvPKhhiPh Unexecuted instantiation: _ZN5doris10ForDecoderIhE19bit_unpack_optimizeInEEvPKhhiPh Unexecuted instantiation: _ZN5doris10ForDecoderItE19bit_unpack_optimizeIlEEvPKhhiPt Unexecuted instantiation: _ZN5doris10ForDecoderItE19bit_unpack_optimizeInEEvPKhhiPt _ZN5doris10ForDecoderIjE19bit_unpack_optimizeIlEEvPKhhiPj Line | Count | Source | 437 | 10 | T* output) { | 438 | 10 | static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value, | 439 | 10 | "bit_unpack_optimize only supports U = int64_t or __int128_t"); | 440 | 10 | constexpr int u_size = sizeof(U); // Size of U | 441 | 10 | constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size) | 442 | 10 | int valid_bit = 0; // How many valid bits | 443 | 10 | int need_bit = 0; // still need | 444 | 10 | size_t input_size = (in_num * bit_width + 7) >> 3; // input's size | 445 | 10 | int full_batch_size = | 446 | 10 | cast_set<int>((input_size >> u_size_shift) | 447 | 10 | << u_size_shift); // Adjust input_size to a multiple of u_size | 448 | 10 | int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size. | 449 | | // The number of bits in input to adjust to multiples of 8 and thus more | 450 | 10 | int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width)); | 451 | | | 452 | | // to ensure that only bit_width bits are valid | 453 | 10 | T output_mask; | 454 | 10 | if (bit_width >= static_cast<int>(sizeof(T) * 8)) { | 455 | 0 | output_mask = static_cast<T>(~T(0)); | 456 | 10 | } else { | 457 | 10 | output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1); | 458 | 10 | } | 459 | | | 460 | 10 | U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking | 461 | | | 462 | 30 | for (int i = 0; i < full_batch_size; i += u_size) { | 463 | 20 | s = 0; | 464 | | | 465 | 20 | s = to_endian<std::endian::big>(*((U*)(input + i))); | 466 | | | 467 | | // Determine what the valid bits are based on u_size | 468 | 20 | valid_bit = u_size << 3; | 469 | | | 470 | | // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop. | 471 | 20 | if (tail_count == 0 && i == full_batch_size - u_size) { | 472 | 10 | valid_bit -= more_bit; | 473 | 10 | s >>= more_bit; | 474 | 10 | } | 475 | | | 476 | 20 | if (need_bit) { | 477 | | // The last time we take away the high bit_width - need_bit, | 478 | | // we need to make up the rest of the need_bit from the width. | 479 | | // Use valid_bit - need_bit to compute high need_bit bits of s | 480 | | // perform an AND operation to ensure that only need_bit bits are valid | 481 | 0 | auto mask = (static_cast<U>(1) << need_bit) - 1; | 482 | 0 | auto shifted = s >> (valid_bit - need_bit); | 483 | 0 | auto masked_result = shifted & mask; | 484 | 0 | if constexpr (sizeof(T) <= 4) { | 485 | 0 | *output |= static_cast<T>(static_cast<uint32_t>(masked_result)); | 486 | | } else { | 487 | | *output |= static_cast<T>(masked_result); | 488 | | } | 489 | 0 | output++; | 490 | 0 | valid_bit -= need_bit; | 491 | 0 | } | 492 | | | 493 | 20 | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 494 | 20 | int remainder = valid_bit - num * bit_width; // How many bits are left to store | 495 | | | 496 | | // Starting with the highest valid bit, take out bit_width bits in sequence | 497 | | // perform an AND operation with output_mask to ensure that only bit_width bits are valid | 498 | | // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end | 499 | | // But since there are still remainder bits that can't be processed, need to add the remainder | 500 | 1.30k | for (int j = 0; j < num; j++) { | 501 | 1.28k | *output = | 502 | 1.28k | static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask); | 503 | 1.28k | output++; | 504 | 1.28k | } | 505 | | | 506 | 20 | if (remainder) { | 507 | | // Process the last remaining remainder bit. | 508 | | // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits. | 509 | | // output = y << (bit_width - remainder) Use the high bit_width - remainder bit | 510 | 0 | if constexpr (sizeof(T) <= 4) { | 511 | 0 | auto masked_value = static_cast<T>( | 512 | 0 | static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1))); | 513 | 0 | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 514 | | } else { | 515 | | auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1))); | 516 | | *output = static_cast<T>(masked_value << (bit_width - remainder)); | 517 | | } | 518 | | // Already have remainder bits, next time need bit_width - remainder bits | 519 | 0 | need_bit = bit_width - remainder; | 520 | 20 | } else { | 521 | 20 | need_bit = 0; | 522 | 20 | } | 523 | 20 | } | 524 | | | 525 | | // remainder | 526 | 10 | if (tail_count) { | 527 | | // Put the tail_count numbers in the input into s in order, each number occupies 8 bit | 528 | 0 | for (int i = 0; i < tail_count; i++) { | 529 | 0 | s <<= 8; | 530 | 0 | s |= input[full_batch_size + i]; | 531 | 0 | } | 532 | | | 533 | | // tail * 8 is the number of bits that are left to process | 534 | | // tail * 8 - more_bit is to remove the last more_bit | 535 | 0 | valid_bit = (tail_count << 3) - more_bit; | 536 | 0 | s >>= more_bit; | 537 | | | 538 | | // same as before | 539 | 0 | if (need_bit) { | 540 | 0 | if constexpr (sizeof(T) <= 4) { | 541 | 0 | *output |= static_cast<T>(static_cast<uint32_t>( | 542 | 0 | (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1))); | 543 | | } else { | 544 | | *output |= static_cast<T>((s >> (valid_bit - need_bit)) & | 545 | | ((static_cast<U>(1) << need_bit) - 1)); | 546 | | } | 547 | 0 | output++; | 548 | 0 | valid_bit -= need_bit; | 549 | 0 | } | 550 | |
| 551 | 0 | int num = valid_bit / bit_width; // How many outputs can be processed at a time | 552 | | | 553 | | // same as before | 554 | 0 | for (int j = 0; j < num; j++) { | 555 | 0 | *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask); | 556 | 0 | output++; | 557 | 0 | } | 558 | 0 | } | 559 | 10 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderIjE19bit_unpack_optimizeInEEvPKhhiPj Unexecuted instantiation: _ZN5doris10ForDecoderImE19bit_unpack_optimizeIlEEvPKhhiPm Unexecuted instantiation: _ZN5doris10ForDecoderImE19bit_unpack_optimizeInEEvPKhhiPm Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE19bit_unpack_optimizeIlEEvPKhhiPS1_ Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE19bit_unpack_optimizeInEEvPKhhiPS1_ Unexecuted instantiation: _ZN5doris10ForDecoderIoE19bit_unpack_optimizeIlEEvPKhhiPo Unexecuted instantiation: _ZN5doris10ForDecoderIoE19bit_unpack_optimizeInEEvPKhhiPo |
560 | | |
561 | | // The reverse of bit_pack method, get original integer data list from packed bits |
562 | | // param[in] input: the packed bits need to unpack |
563 | | // param[in] in_num: the integer number in packed bits |
564 | | // param[in] bit_width: how many bit we used to store each integer data |
565 | | // param[out] output: the original integer data list |
566 | | template <typename T> |
567 | 162k | void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) { |
568 | | /* |
569 | | When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times. |
570 | | When bit_width > 64, we must use __int128_t and unroll the loop 16 times. |
571 | | */ |
572 | 162k | if (bit_width <= 32) { |
573 | 41.2k | bit_unpack_optimize<int64_t>(input, in_num, bit_width, output); |
574 | 121k | } else { |
575 | 121k | bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output); |
576 | 121k | } |
577 | 162k | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE10bit_unpackEPKhhiPa Unexecuted instantiation: _ZN5doris10ForDecoderIsE10bit_unpackEPKhhiPs _ZN5doris10ForDecoderIiE10bit_unpackEPKhhiPi Line | Count | Source | 567 | 18 | void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) { | 568 | | /* | 569 | | When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times. | 570 | | When bit_width > 64, we must use __int128_t and unroll the loop 16 times. | 571 | | */ | 572 | 18 | if (bit_width <= 32) { | 573 | 18 | bit_unpack_optimize<int64_t>(input, in_num, bit_width, output); | 574 | 18 | } else { | 575 | 0 | bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output); | 576 | 0 | } | 577 | 18 | } |
_ZN5doris10ForDecoderIlE10bit_unpackEPKhhiPl Line | Count | Source | 567 | 48.9k | void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) { | 568 | | /* | 569 | | When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times. | 570 | | When bit_width > 64, we must use __int128_t and unroll the loop 16 times. | 571 | | */ | 572 | 48.9k | if (bit_width <= 32) { | 573 | 24.6k | bit_unpack_optimize<int64_t>(input, in_num, bit_width, output); | 574 | 24.6k | } else { | 575 | 24.3k | bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output); | 576 | 24.3k | } | 577 | 48.9k | } |
_ZN5doris10ForDecoderInE10bit_unpackEPKhhiPn Line | Count | Source | 567 | 113k | void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) { | 568 | | /* | 569 | | When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times. | 570 | | When bit_width > 64, we must use __int128_t and unroll the loop 16 times. | 571 | | */ | 572 | 113k | if (bit_width <= 32) { | 573 | 16.5k | bit_unpack_optimize<int64_t>(input, in_num, bit_width, output); | 574 | 97.0k | } else { | 575 | 97.0k | bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output); | 576 | 97.0k | } | 577 | 113k | } |
Unexecuted instantiation: _ZN5doris10ForDecoderIhE10bit_unpackEPKhhiPh Unexecuted instantiation: _ZN5doris10ForDecoderItE10bit_unpackEPKhhiPt _ZN5doris10ForDecoderIjE10bit_unpackEPKhhiPj Line | Count | Source | 567 | 10 | void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) { | 568 | | /* | 569 | | When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times. | 570 | | When bit_width > 64, we must use __int128_t and unroll the loop 16 times. | 571 | | */ | 572 | 10 | if (bit_width <= 32) { | 573 | 10 | bit_unpack_optimize<int64_t>(input, in_num, bit_width, output); | 574 | 10 | } else { | 575 | 0 | bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output); | 576 | 0 | } | 577 | 10 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderImE10bit_unpackEPKhhiPm Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE10bit_unpackEPKhhiPS1_ Unexecuted instantiation: _ZN5doris10ForDecoderIoE10bit_unpackEPKhhiPo |
578 | | |
579 | | template <typename T> |
580 | 8.35M | void ForDecoder<T>::decode_current_frame(T* output) { |
581 | 8.35M | uint32_t frame_index = _current_index / _max_frame_size; |
582 | 8.35M | if (frame_index == _current_decoded_frame) { |
583 | 8.25M | return; // current frame already decoded |
584 | 8.25M | } |
585 | 97.8k | _current_decoded_frame = frame_index; |
586 | 97.8k | uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index)); |
587 | | |
588 | 97.8k | uint32_t base_offset = _frame_offsets[_current_decoded_frame]; |
589 | 97.8k | T min = 0; |
590 | 97.8k | uint32_t delta_offset = 0; |
591 | 97.8k | if constexpr (sizeof(T) == 16) { |
592 | 48.8k | min = static_cast<T>(decode_fixed128_le(_buffer + base_offset)); |
593 | 48.8k | delta_offset = base_offset + 16; |
594 | 48.9k | } else if constexpr (sizeof(T) == 8) { |
595 | 48.9k | min = static_cast<T>(decode_fixed64_le(_buffer + base_offset)); |
596 | 48.9k | delta_offset = base_offset + 8; |
597 | 48.9k | } else { |
598 | 28 | min = static_cast<T>(decode_fixed32_le(_buffer + base_offset)); |
599 | 28 | delta_offset = base_offset + 4; |
600 | 28 | } |
601 | | |
602 | 97.8k | uint8_t bit_width = _bit_widths[_current_decoded_frame]; |
603 | | |
604 | 97.8k | bool is_original_value = _storage_formats[_current_decoded_frame] == 2; |
605 | 97.8k | if (is_original_value) { |
606 | 0 | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output); |
607 | 97.8k | } else { |
608 | 97.8k | bool is_ascending = _storage_formats[_current_decoded_frame] == 1; |
609 | 97.8k | std::vector<T> delta_values(current_frame_size); |
610 | 97.8k | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data()); |
611 | 97.8k | if (is_ascending) { |
612 | 902 | T pre_value = min; |
613 | 7.74k | for (uint8_t i = 0; i < current_frame_size; i++) { |
614 | 6.84k | T value = delta_values[i] + pre_value; |
615 | 6.84k | output[i] = value; |
616 | 6.84k | pre_value = value; |
617 | 6.84k | } |
618 | 96.9k | } else { |
619 | 8.45M | for (uint8_t i = 0; i < current_frame_size; i++) { |
620 | 8.35M | output[i] = delta_values[i] + min; |
621 | 8.35M | } |
622 | 96.9k | } |
623 | 97.8k | } |
624 | 97.8k | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE20decode_current_frameEPa Unexecuted instantiation: _ZN5doris10ForDecoderIsE20decode_current_frameEPs _ZN5doris10ForDecoderIiE20decode_current_frameEPi Line | Count | Source | 580 | 20 | void ForDecoder<T>::decode_current_frame(T* output) { | 581 | 20 | uint32_t frame_index = _current_index / _max_frame_size; | 582 | 20 | if (frame_index == _current_decoded_frame) { | 583 | 2 | return; // current frame already decoded | 584 | 2 | } | 585 | 18 | _current_decoded_frame = frame_index; | 586 | 18 | uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index)); | 587 | | | 588 | 18 | uint32_t base_offset = _frame_offsets[_current_decoded_frame]; | 589 | 18 | T min = 0; | 590 | 18 | uint32_t delta_offset = 0; | 591 | | if constexpr (sizeof(T) == 16) { | 592 | | min = static_cast<T>(decode_fixed128_le(_buffer + base_offset)); | 593 | | delta_offset = base_offset + 16; | 594 | | } else if constexpr (sizeof(T) == 8) { | 595 | | min = static_cast<T>(decode_fixed64_le(_buffer + base_offset)); | 596 | | delta_offset = base_offset + 8; | 597 | 18 | } else { | 598 | 18 | min = static_cast<T>(decode_fixed32_le(_buffer + base_offset)); | 599 | 18 | delta_offset = base_offset + 4; | 600 | 18 | } | 601 | | | 602 | 18 | uint8_t bit_width = _bit_widths[_current_decoded_frame]; | 603 | | | 604 | 18 | bool is_original_value = _storage_formats[_current_decoded_frame] == 2; | 605 | 18 | if (is_original_value) { | 606 | 0 | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output); | 607 | 18 | } else { | 608 | 18 | bool is_ascending = _storage_formats[_current_decoded_frame] == 1; | 609 | 18 | std::vector<T> delta_values(current_frame_size); | 610 | 18 | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data()); | 611 | 18 | if (is_ascending) { | 612 | 18 | T pre_value = min; | 613 | 1.56k | for (uint8_t i = 0; i < current_frame_size; i++) { | 614 | 1.54k | T value = delta_values[i] + pre_value; | 615 | 1.54k | output[i] = value; | 616 | 1.54k | pre_value = value; | 617 | 1.54k | } | 618 | 18 | } else { | 619 | 0 | for (uint8_t i = 0; i < current_frame_size; i++) { | 620 | 0 | output[i] = delta_values[i] + min; | 621 | 0 | } | 622 | 0 | } | 623 | 18 | } | 624 | 18 | } |
_ZN5doris10ForDecoderIlE20decode_current_frameEPl Line | Count | Source | 580 | 4.17M | void ForDecoder<T>::decode_current_frame(T* output) { | 581 | 4.17M | uint32_t frame_index = _current_index / _max_frame_size; | 582 | 4.17M | if (frame_index == _current_decoded_frame) { | 583 | 4.12M | return; // current frame already decoded | 584 | 4.12M | } | 585 | 48.9k | _current_decoded_frame = frame_index; | 586 | 48.9k | uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index)); | 587 | | | 588 | 48.9k | uint32_t base_offset = _frame_offsets[_current_decoded_frame]; | 589 | 48.9k | T min = 0; | 590 | 48.9k | uint32_t delta_offset = 0; | 591 | | if constexpr (sizeof(T) == 16) { | 592 | | min = static_cast<T>(decode_fixed128_le(_buffer + base_offset)); | 593 | | delta_offset = base_offset + 16; | 594 | 48.9k | } else if constexpr (sizeof(T) == 8) { | 595 | 48.9k | min = static_cast<T>(decode_fixed64_le(_buffer + base_offset)); | 596 | 48.9k | delta_offset = base_offset + 8; | 597 | | } else { | 598 | | min = static_cast<T>(decode_fixed32_le(_buffer + base_offset)); | 599 | | delta_offset = base_offset + 4; | 600 | | } | 601 | | | 602 | 48.9k | uint8_t bit_width = _bit_widths[_current_decoded_frame]; | 603 | | | 604 | 48.9k | bool is_original_value = _storage_formats[_current_decoded_frame] == 2; | 605 | 48.9k | if (is_original_value) { | 606 | 0 | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output); | 607 | 48.9k | } else { | 608 | 48.9k | bool is_ascending = _storage_formats[_current_decoded_frame] == 1; | 609 | 48.9k | std::vector<T> delta_values(current_frame_size); | 610 | 48.9k | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data()); | 611 | 48.9k | if (is_ascending) { | 612 | 446 | T pre_value = min; | 613 | 3.79k | for (uint8_t i = 0; i < current_frame_size; i++) { | 614 | 3.34k | T value = delta_values[i] + pre_value; | 615 | 3.34k | output[i] = value; | 616 | 3.34k | pre_value = value; | 617 | 3.34k | } | 618 | 48.4k | } else { | 619 | 4.22M | for (uint8_t i = 0; i < current_frame_size; i++) { | 620 | 4.17M | output[i] = delta_values[i] + min; | 621 | 4.17M | } | 622 | 48.4k | } | 623 | 48.9k | } | 624 | 48.9k | } |
_ZN5doris10ForDecoderInE20decode_current_frameEPn Line | Count | Source | 580 | 4.17M | void ForDecoder<T>::decode_current_frame(T* output) { | 581 | 4.17M | uint32_t frame_index = _current_index / _max_frame_size; | 582 | 4.17M | if (frame_index == _current_decoded_frame) { | 583 | 4.12M | return; // current frame already decoded | 584 | 4.12M | } | 585 | 48.8k | _current_decoded_frame = frame_index; | 586 | 48.8k | uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index)); | 587 | | | 588 | 48.8k | uint32_t base_offset = _frame_offsets[_current_decoded_frame]; | 589 | 48.8k | T min = 0; | 590 | 48.8k | uint32_t delta_offset = 0; | 591 | 48.8k | if constexpr (sizeof(T) == 16) { | 592 | 48.8k | min = static_cast<T>(decode_fixed128_le(_buffer + base_offset)); | 593 | 48.8k | delta_offset = base_offset + 16; | 594 | | } else if constexpr (sizeof(T) == 8) { | 595 | | min = static_cast<T>(decode_fixed64_le(_buffer + base_offset)); | 596 | | delta_offset = base_offset + 8; | 597 | | } else { | 598 | | min = static_cast<T>(decode_fixed32_le(_buffer + base_offset)); | 599 | | delta_offset = base_offset + 4; | 600 | | } | 601 | | | 602 | 48.8k | uint8_t bit_width = _bit_widths[_current_decoded_frame]; | 603 | | | 604 | 48.8k | bool is_original_value = _storage_formats[_current_decoded_frame] == 2; | 605 | 48.8k | if (is_original_value) { | 606 | 0 | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output); | 607 | 48.8k | } else { | 608 | 48.8k | bool is_ascending = _storage_formats[_current_decoded_frame] == 1; | 609 | 48.8k | std::vector<T> delta_values(current_frame_size); | 610 | 48.8k | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data()); | 611 | 48.8k | if (is_ascending) { | 612 | 428 | T pre_value = min; | 613 | 1.10k | for (uint8_t i = 0; i < current_frame_size; i++) { | 614 | 676 | T value = delta_values[i] + pre_value; | 615 | 676 | output[i] = value; | 616 | 676 | pre_value = value; | 617 | 676 | } | 618 | 48.4k | } else { | 619 | 4.22M | for (uint8_t i = 0; i < current_frame_size; i++) { | 620 | 4.17M | output[i] = delta_values[i] + min; | 621 | 4.17M | } | 622 | 48.4k | } | 623 | 48.8k | } | 624 | 48.8k | } |
Unexecuted instantiation: _ZN5doris10ForDecoderIhE20decode_current_frameEPh Unexecuted instantiation: _ZN5doris10ForDecoderItE20decode_current_frameEPt _ZN5doris10ForDecoderIjE20decode_current_frameEPj Line | Count | Source | 580 | 10 | void ForDecoder<T>::decode_current_frame(T* output) { | 581 | 10 | uint32_t frame_index = _current_index / _max_frame_size; | 582 | 10 | if (frame_index == _current_decoded_frame) { | 583 | 0 | return; // current frame already decoded | 584 | 0 | } | 585 | 10 | _current_decoded_frame = frame_index; | 586 | 10 | uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index)); | 587 | | | 588 | 10 | uint32_t base_offset = _frame_offsets[_current_decoded_frame]; | 589 | 10 | T min = 0; | 590 | 10 | uint32_t delta_offset = 0; | 591 | | if constexpr (sizeof(T) == 16) { | 592 | | min = static_cast<T>(decode_fixed128_le(_buffer + base_offset)); | 593 | | delta_offset = base_offset + 16; | 594 | | } else if constexpr (sizeof(T) == 8) { | 595 | | min = static_cast<T>(decode_fixed64_le(_buffer + base_offset)); | 596 | | delta_offset = base_offset + 8; | 597 | 10 | } else { | 598 | 10 | min = static_cast<T>(decode_fixed32_le(_buffer + base_offset)); | 599 | 10 | delta_offset = base_offset + 4; | 600 | 10 | } | 601 | | | 602 | 10 | uint8_t bit_width = _bit_widths[_current_decoded_frame]; | 603 | | | 604 | 10 | bool is_original_value = _storage_formats[_current_decoded_frame] == 2; | 605 | 10 | if (is_original_value) { | 606 | 0 | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output); | 607 | 10 | } else { | 608 | 10 | bool is_ascending = _storage_formats[_current_decoded_frame] == 1; | 609 | 10 | std::vector<T> delta_values(current_frame_size); | 610 | 10 | bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data()); | 611 | 10 | if (is_ascending) { | 612 | 10 | T pre_value = min; | 613 | 1.29k | for (uint8_t i = 0; i < current_frame_size; i++) { | 614 | 1.28k | T value = delta_values[i] + pre_value; | 615 | 1.28k | output[i] = value; | 616 | 1.28k | pre_value = value; | 617 | 1.28k | } | 618 | 10 | } else { | 619 | 0 | for (uint8_t i = 0; i < current_frame_size; i++) { | 620 | 0 | output[i] = delta_values[i] + min; | 621 | 0 | } | 622 | 0 | } | 623 | 10 | } | 624 | 10 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderImE20decode_current_frameEPm Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE20decode_current_frameEPS1_ Unexecuted instantiation: _ZN5doris10ForDecoderIoE20decode_current_frameEPo |
625 | | |
626 | | template <typename T> |
627 | 24 | T ForDecoder<T>::decode_frame_min_value(uint32_t frame_index) { |
628 | 24 | uint32_t min_offset = _frame_offsets[frame_index]; |
629 | 24 | T min = 0; |
630 | 24 | if constexpr (sizeof(T) == 16) { |
631 | 0 | min = static_cast<T>(decode_fixed128_le(_buffer + min_offset)); |
632 | 24 | } else if constexpr (sizeof(T) == 8) { |
633 | 24 | min = static_cast<T>(decode_fixed64_le(_buffer + min_offset)); |
634 | 24 | } else { |
635 | 0 | min = static_cast<T>(decode_fixed32_le(_buffer + min_offset)); |
636 | 0 | } |
637 | 24 | return min; |
638 | 24 | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE22decode_frame_min_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderIsE22decode_frame_min_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderIiE22decode_frame_min_valueEj _ZN5doris10ForDecoderIlE22decode_frame_min_valueEj Line | Count | Source | 627 | 24 | T ForDecoder<T>::decode_frame_min_value(uint32_t frame_index) { | 628 | 24 | uint32_t min_offset = _frame_offsets[frame_index]; | 629 | 24 | T min = 0; | 630 | | if constexpr (sizeof(T) == 16) { | 631 | | min = static_cast<T>(decode_fixed128_le(_buffer + min_offset)); | 632 | 24 | } else if constexpr (sizeof(T) == 8) { | 633 | 24 | min = static_cast<T>(decode_fixed64_le(_buffer + min_offset)); | 634 | | } else { | 635 | | min = static_cast<T>(decode_fixed32_le(_buffer + min_offset)); | 636 | | } | 637 | 24 | return min; | 638 | 24 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderInE22decode_frame_min_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderIhE22decode_frame_min_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderItE22decode_frame_min_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderIjE22decode_frame_min_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderImE22decode_frame_min_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE22decode_frame_min_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderIoE22decode_frame_min_valueEj |
639 | | |
640 | | template <typename T> |
641 | 8.35M | T* ForDecoder<T>::copy_value(T* val, size_t count) { |
642 | 8.35M | memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count); |
643 | 8.35M | _current_index += count; |
644 | 8.35M | val += count; |
645 | 8.35M | return val; |
646 | 8.35M | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE10copy_valueEPam Unexecuted instantiation: _ZN5doris10ForDecoderIsE10copy_valueEPsm _ZN5doris10ForDecoderIiE10copy_valueEPim Line | Count | Source | 641 | 16 | T* ForDecoder<T>::copy_value(T* val, size_t count) { | 642 | 16 | memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count); | 643 | 16 | _current_index += count; | 644 | 16 | val += count; | 645 | 16 | return val; | 646 | 16 | } |
_ZN5doris10ForDecoderIlE10copy_valueEPlm Line | Count | Source | 641 | 4.17M | T* ForDecoder<T>::copy_value(T* val, size_t count) { | 642 | 4.17M | memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count); | 643 | 4.17M | _current_index += count; | 644 | 4.17M | val += count; | 645 | 4.17M | return val; | 646 | 4.17M | } |
_ZN5doris10ForDecoderInE10copy_valueEPnm Line | Count | Source | 641 | 4.17M | T* ForDecoder<T>::copy_value(T* val, size_t count) { | 642 | 4.17M | memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count); | 643 | 4.17M | _current_index += count; | 644 | 4.17M | val += count; | 645 | 4.17M | return val; | 646 | 4.17M | } |
Unexecuted instantiation: _ZN5doris10ForDecoderIhE10copy_valueEPhm Unexecuted instantiation: _ZN5doris10ForDecoderItE10copy_valueEPtm _ZN5doris10ForDecoderIjE10copy_valueEPjm Line | Count | Source | 641 | 6 | T* ForDecoder<T>::copy_value(T* val, size_t count) { | 642 | 6 | memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count); | 643 | 6 | _current_index += count; | 644 | 6 | val += count; | 645 | 6 | return val; | 646 | 6 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderImE10copy_valueEPmm Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE10copy_valueEPS1_m Unexecuted instantiation: _ZN5doris10ForDecoderIoE10copy_valueEPom |
647 | | |
648 | | template <typename T> |
649 | 8.35M | bool ForDecoder<T>::get_batch(T* val, size_t count) { |
650 | 8.35M | if (_current_index + count > _values_num) { |
651 | 2 | return false; |
652 | 2 | } |
653 | | |
654 | 8.35M | decode_current_frame(_out_buffer.data()); |
655 | | |
656 | 8.35M | if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) { |
657 | 8.32M | copy_value(val, count); |
658 | 8.32M | return true; |
659 | 8.32M | } |
660 | | |
661 | | // 1. padding one frame |
662 | 32.7k | size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index; |
663 | 32.7k | val = copy_value(val, padding_num); |
664 | | |
665 | | // 2. process frame by frame |
666 | 32.7k | size_t frame_count = (count - padding_num) / _max_frame_size; |
667 | 32.8k | for (size_t i = 0; i < frame_count; i++) { |
668 | | // directly decode value to the output, don't buffer the value |
669 | 14 | decode_current_frame(val); |
670 | 14 | _current_index += _max_frame_size; |
671 | 14 | val += _max_frame_size; |
672 | 14 | } |
673 | | |
674 | | // 3. process remaining value |
675 | 32.7k | size_t remaining_num = (count - padding_num) % _max_frame_size; |
676 | 32.7k | if (remaining_num > 0) { |
677 | 8 | decode_current_frame(_out_buffer.data()); |
678 | 8 | val = copy_value(val, remaining_num); |
679 | 8 | } |
680 | | |
681 | 32.7k | return true; |
682 | 8.35M | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE9get_batchEPam Unexecuted instantiation: _ZN5doris10ForDecoderIsE9get_batchEPsm _ZN5doris10ForDecoderIiE9get_batchEPim Line | Count | Source | 649 | 16 | bool ForDecoder<T>::get_batch(T* val, size_t count) { | 650 | 16 | if (_current_index + count > _values_num) { | 651 | 2 | return false; | 652 | 2 | } | 653 | | | 654 | 14 | decode_current_frame(_out_buffer.data()); | 655 | | | 656 | 14 | if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) { | 657 | 8 | copy_value(val, count); | 658 | 8 | return true; | 659 | 8 | } | 660 | | | 661 | | // 1. padding one frame | 662 | 6 | size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index; | 663 | 6 | val = copy_value(val, padding_num); | 664 | | | 665 | | // 2. process frame by frame | 666 | 6 | size_t frame_count = (count - padding_num) / _max_frame_size; | 667 | 10 | for (size_t i = 0; i < frame_count; i++) { | 668 | | // directly decode value to the output, don't buffer the value | 669 | 4 | decode_current_frame(val); | 670 | 4 | _current_index += _max_frame_size; | 671 | 4 | val += _max_frame_size; | 672 | 4 | } | 673 | | | 674 | | // 3. process remaining value | 675 | 6 | size_t remaining_num = (count - padding_num) % _max_frame_size; | 676 | 6 | if (remaining_num > 0) { | 677 | 2 | decode_current_frame(_out_buffer.data()); | 678 | 2 | val = copy_value(val, remaining_num); | 679 | 2 | } | 680 | | | 681 | 6 | return true; | 682 | 14 | } |
_ZN5doris10ForDecoderIlE9get_batchEPlm Line | Count | Source | 649 | 4.17M | bool ForDecoder<T>::get_batch(T* val, size_t count) { | 650 | 4.17M | if (_current_index + count > _values_num) { | 651 | 0 | return false; | 652 | 0 | } | 653 | | | 654 | 4.17M | decode_current_frame(_out_buffer.data()); | 655 | | | 656 | 4.17M | if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) { | 657 | 4.16M | copy_value(val, count); | 658 | 4.16M | return true; | 659 | 4.16M | } | 660 | | | 661 | | // 1. padding one frame | 662 | 16.3k | size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index; | 663 | 16.3k | val = copy_value(val, padding_num); | 664 | | | 665 | | // 2. process frame by frame | 666 | 16.3k | size_t frame_count = (count - padding_num) / _max_frame_size; | 667 | 16.3k | for (size_t i = 0; i < frame_count; i++) { | 668 | | // directly decode value to the output, don't buffer the value | 669 | 6 | decode_current_frame(val); | 670 | 6 | _current_index += _max_frame_size; | 671 | 6 | val += _max_frame_size; | 672 | 6 | } | 673 | | | 674 | | // 3. process remaining value | 675 | 16.3k | size_t remaining_num = (count - padding_num) % _max_frame_size; | 676 | 16.3k | if (remaining_num > 0) { | 677 | 6 | decode_current_frame(_out_buffer.data()); | 678 | 6 | val = copy_value(val, remaining_num); | 679 | 6 | } | 680 | | | 681 | 16.3k | return true; | 682 | 4.17M | } |
_ZN5doris10ForDecoderInE9get_batchEPnm Line | Count | Source | 649 | 4.17M | bool ForDecoder<T>::get_batch(T* val, size_t count) { | 650 | 4.17M | if (_current_index + count > _values_num) { | 651 | 0 | return false; | 652 | 0 | } | 653 | | | 654 | 4.17M | decode_current_frame(_out_buffer.data()); | 655 | | | 656 | 4.17M | if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) { | 657 | 4.16M | copy_value(val, count); | 658 | 4.16M | return true; | 659 | 4.16M | } | 660 | | | 661 | | // 1. padding one frame | 662 | 16.3k | size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index; | 663 | 16.3k | val = copy_value(val, padding_num); | 664 | | | 665 | | // 2. process frame by frame | 666 | 16.3k | size_t frame_count = (count - padding_num) / _max_frame_size; | 667 | 16.3k | for (size_t i = 0; i < frame_count; i++) { | 668 | | // directly decode value to the output, don't buffer the value | 669 | 0 | decode_current_frame(val); | 670 | 0 | _current_index += _max_frame_size; | 671 | 0 | val += _max_frame_size; | 672 | 0 | } | 673 | | | 674 | | // 3. process remaining value | 675 | 16.3k | size_t remaining_num = (count - padding_num) % _max_frame_size; | 676 | 16.3k | if (remaining_num > 0) { | 677 | 0 | decode_current_frame(_out_buffer.data()); | 678 | 0 | val = copy_value(val, remaining_num); | 679 | 0 | } | 680 | | | 681 | 16.3k | return true; | 682 | 4.17M | } |
Unexecuted instantiation: _ZN5doris10ForDecoderIhE9get_batchEPhm Unexecuted instantiation: _ZN5doris10ForDecoderItE9get_batchEPtm _ZN5doris10ForDecoderIjE9get_batchEPjm Line | Count | Source | 649 | 6 | bool ForDecoder<T>::get_batch(T* val, size_t count) { | 650 | 6 | if (_current_index + count > _values_num) { | 651 | 0 | return false; | 652 | 0 | } | 653 | | | 654 | 6 | decode_current_frame(_out_buffer.data()); | 655 | | | 656 | 6 | if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) { | 657 | 0 | copy_value(val, count); | 658 | 0 | return true; | 659 | 0 | } | 660 | | | 661 | | // 1. padding one frame | 662 | 6 | size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index; | 663 | 6 | val = copy_value(val, padding_num); | 664 | | | 665 | | // 2. process frame by frame | 666 | 6 | size_t frame_count = (count - padding_num) / _max_frame_size; | 667 | 10 | for (size_t i = 0; i < frame_count; i++) { | 668 | | // directly decode value to the output, don't buffer the value | 669 | 4 | decode_current_frame(val); | 670 | 4 | _current_index += _max_frame_size; | 671 | 4 | val += _max_frame_size; | 672 | 4 | } | 673 | | | 674 | | // 3. process remaining value | 675 | 6 | size_t remaining_num = (count - padding_num) % _max_frame_size; | 676 | 6 | if (remaining_num > 0) { | 677 | 0 | decode_current_frame(_out_buffer.data()); | 678 | 0 | val = copy_value(val, remaining_num); | 679 | 0 | } | 680 | | | 681 | 6 | return true; | 682 | 6 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderImE9get_batchEPmm Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE9get_batchEPS1_m Unexecuted instantiation: _ZN5doris10ForDecoderIoE9get_batchEPom |
683 | | |
684 | | template <typename T> |
685 | 6 | bool ForDecoder<T>::skip(int32_t skip_num) { |
686 | 6 | if (_current_index + skip_num >= _values_num) { |
687 | 0 | return false; |
688 | 0 | } |
689 | 6 | _current_index = _current_index + skip_num; |
690 | 6 | return true; |
691 | 6 | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE4skipEi Unexecuted instantiation: _ZN5doris10ForDecoderIsE4skipEi Unexecuted instantiation: _ZN5doris10ForDecoderIiE4skipEi Unexecuted instantiation: _ZN5doris10ForDecoderIlE4skipEi Unexecuted instantiation: _ZN5doris10ForDecoderInE4skipEi Unexecuted instantiation: _ZN5doris10ForDecoderIhE4skipEi Unexecuted instantiation: _ZN5doris10ForDecoderItE4skipEi _ZN5doris10ForDecoderIjE4skipEi Line | Count | Source | 685 | 6 | bool ForDecoder<T>::skip(int32_t skip_num) { | 686 | 6 | if (_current_index + skip_num >= _values_num) { | 687 | 0 | return false; | 688 | 0 | } | 689 | 6 | _current_index = _current_index + skip_num; | 690 | 6 | return true; | 691 | 6 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderImE4skipEi Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE4skipEi Unexecuted instantiation: _ZN5doris10ForDecoderIoE4skipEi |
692 | | |
693 | | template <typename T> |
694 | 12 | uint32_t ForDecoder<T>::seek_last_frame_before_value(T target) { |
695 | | // first of all, find the first frame >= target |
696 | 12 | uint32_t left = 0; |
697 | 12 | uint32_t right = _frame_count; |
698 | 36 | while (left < right) { |
699 | 24 | uint32_t mid = left + (right - left) / 2; |
700 | 24 | T midValue = decode_frame_min_value(mid); |
701 | 24 | if (midValue < target) { |
702 | 12 | left = mid + 1; |
703 | 12 | } else { |
704 | 12 | right = mid; |
705 | 12 | } |
706 | 24 | } |
707 | | // after loop, left is the first frame >= target |
708 | 12 | if (left == 0) { |
709 | | // all frames are >= target, not found |
710 | 4 | return _frame_count; |
711 | 4 | } |
712 | | // otherwise previous frame is the last frame < target |
713 | 8 | return left - 1; |
714 | 12 | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE28seek_last_frame_before_valueEa Unexecuted instantiation: _ZN5doris10ForDecoderIsE28seek_last_frame_before_valueEs Unexecuted instantiation: _ZN5doris10ForDecoderIiE28seek_last_frame_before_valueEi _ZN5doris10ForDecoderIlE28seek_last_frame_before_valueEl Line | Count | Source | 694 | 12 | uint32_t ForDecoder<T>::seek_last_frame_before_value(T target) { | 695 | | // first of all, find the first frame >= target | 696 | 12 | uint32_t left = 0; | 697 | 12 | uint32_t right = _frame_count; | 698 | 36 | while (left < right) { | 699 | 24 | uint32_t mid = left + (right - left) / 2; | 700 | 24 | T midValue = decode_frame_min_value(mid); | 701 | 24 | if (midValue < target) { | 702 | 12 | left = mid + 1; | 703 | 12 | } else { | 704 | 12 | right = mid; | 705 | 12 | } | 706 | 24 | } | 707 | | // after loop, left is the first frame >= target | 708 | 12 | if (left == 0) { | 709 | | // all frames are >= target, not found | 710 | 4 | return _frame_count; | 711 | 4 | } | 712 | | // otherwise previous frame is the last frame < target | 713 | 8 | return left - 1; | 714 | 12 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderInE28seek_last_frame_before_valueEn Unexecuted instantiation: _ZN5doris10ForDecoderIhE28seek_last_frame_before_valueEh Unexecuted instantiation: _ZN5doris10ForDecoderItE28seek_last_frame_before_valueEt Unexecuted instantiation: _ZN5doris10ForDecoderIjE28seek_last_frame_before_valueEj Unexecuted instantiation: _ZN5doris10ForDecoderImE28seek_last_frame_before_valueEm Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE28seek_last_frame_before_valueES1_ Unexecuted instantiation: _ZN5doris10ForDecoderIoE28seek_last_frame_before_valueEo |
715 | | |
716 | | template <typename T> |
717 | | bool ForDecoder<T>::seek_lower_bound_inside_frame(uint32_t frame_index, T target, |
718 | 8 | bool* exact_match) { |
719 | 8 | _current_index = frame_index * _max_frame_size; |
720 | 8 | decode_current_frame(_out_buffer.data()); |
721 | 8 | auto end = _out_buffer.begin() + frame_size(frame_index); |
722 | 8 | auto pos = std::lower_bound(_out_buffer.begin(), end, target); |
723 | 8 | if (pos != end) { // found in this frame |
724 | 4 | auto pos_in_frame = cast_set<uint32_t>(std::distance(_out_buffer.begin(), pos)); |
725 | 4 | *exact_match = _out_buffer[pos_in_frame] == target; |
726 | 4 | _current_index += pos_in_frame; |
727 | 4 | return true; |
728 | 4 | } |
729 | 4 | return false; |
730 | 8 | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE29seek_lower_bound_inside_frameEjaPb Unexecuted instantiation: _ZN5doris10ForDecoderIsE29seek_lower_bound_inside_frameEjsPb Unexecuted instantiation: _ZN5doris10ForDecoderIiE29seek_lower_bound_inside_frameEjiPb _ZN5doris10ForDecoderIlE29seek_lower_bound_inside_frameEjlPb Line | Count | Source | 718 | 8 | bool* exact_match) { | 719 | 8 | _current_index = frame_index * _max_frame_size; | 720 | 8 | decode_current_frame(_out_buffer.data()); | 721 | 8 | auto end = _out_buffer.begin() + frame_size(frame_index); | 722 | 8 | auto pos = std::lower_bound(_out_buffer.begin(), end, target); | 723 | 8 | if (pos != end) { // found in this frame | 724 | 4 | auto pos_in_frame = cast_set<uint32_t>(std::distance(_out_buffer.begin(), pos)); | 725 | 4 | *exact_match = _out_buffer[pos_in_frame] == target; | 726 | 4 | _current_index += pos_in_frame; | 727 | 4 | return true; | 728 | 4 | } | 729 | 4 | return false; | 730 | 8 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderInE29seek_lower_bound_inside_frameEjnPb Unexecuted instantiation: _ZN5doris10ForDecoderIhE29seek_lower_bound_inside_frameEjhPb Unexecuted instantiation: _ZN5doris10ForDecoderItE29seek_lower_bound_inside_frameEjtPb Unexecuted instantiation: _ZN5doris10ForDecoderIjE29seek_lower_bound_inside_frameEjjPb Unexecuted instantiation: _ZN5doris10ForDecoderImE29seek_lower_bound_inside_frameEjmPb Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE29seek_lower_bound_inside_frameEjS1_Pb Unexecuted instantiation: _ZN5doris10ForDecoderIoE29seek_lower_bound_inside_frameEjoPb |
731 | | |
732 | | template <typename T> |
733 | 12 | bool ForDecoder<T>::seek_at_or_after_value(const void* value, bool* exact_match) { |
734 | 12 | T target = *reinterpret_cast<const T*>(value); |
735 | 12 | uint32_t frame_to_search = seek_last_frame_before_value(target); |
736 | 12 | if (frame_to_search == _frame_count) { |
737 | | // all frames are >= target, the searched value must the be first value |
738 | 4 | _current_index = 0; |
739 | 4 | decode_current_frame(_out_buffer.data()); |
740 | 4 | *exact_match = _out_buffer[0] == target; |
741 | 4 | return true; |
742 | 4 | } |
743 | | // binary search inside the last frame < target |
744 | 8 | bool found = seek_lower_bound_inside_frame(frame_to_search, target, exact_match); |
745 | | // if not found, all values in the last frame are less than target. |
746 | | // then the searched value must be the first value of the next frame. |
747 | 8 | if (!found && frame_to_search < _frame_count - 1) { |
748 | 2 | _current_index = (frame_to_search + 1) * _max_frame_size; |
749 | 2 | decode_current_frame(_out_buffer.data()); |
750 | 2 | *exact_match = _out_buffer[0] == target; |
751 | 2 | return true; |
752 | 2 | } |
753 | 6 | return found; |
754 | 8 | } Unexecuted instantiation: _ZN5doris10ForDecoderIaE22seek_at_or_after_valueEPKvPb Unexecuted instantiation: _ZN5doris10ForDecoderIsE22seek_at_or_after_valueEPKvPb Unexecuted instantiation: _ZN5doris10ForDecoderIiE22seek_at_or_after_valueEPKvPb _ZN5doris10ForDecoderIlE22seek_at_or_after_valueEPKvPb Line | Count | Source | 733 | 12 | bool ForDecoder<T>::seek_at_or_after_value(const void* value, bool* exact_match) { | 734 | 12 | T target = *reinterpret_cast<const T*>(value); | 735 | 12 | uint32_t frame_to_search = seek_last_frame_before_value(target); | 736 | 12 | if (frame_to_search == _frame_count) { | 737 | | // all frames are >= target, the searched value must the be first value | 738 | 4 | _current_index = 0; | 739 | 4 | decode_current_frame(_out_buffer.data()); | 740 | 4 | *exact_match = _out_buffer[0] == target; | 741 | 4 | return true; | 742 | 4 | } | 743 | | // binary search inside the last frame < target | 744 | 8 | bool found = seek_lower_bound_inside_frame(frame_to_search, target, exact_match); | 745 | | // if not found, all values in the last frame are less than target. | 746 | | // then the searched value must be the first value of the next frame. | 747 | 8 | if (!found && frame_to_search < _frame_count - 1) { | 748 | 2 | _current_index = (frame_to_search + 1) * _max_frame_size; | 749 | 2 | decode_current_frame(_out_buffer.data()); | 750 | 2 | *exact_match = _out_buffer[0] == target; | 751 | 2 | return true; | 752 | 2 | } | 753 | 6 | return found; | 754 | 8 | } |
Unexecuted instantiation: _ZN5doris10ForDecoderInE22seek_at_or_after_valueEPKvPb Unexecuted instantiation: _ZN5doris10ForDecoderIhE22seek_at_or_after_valueEPKvPb Unexecuted instantiation: _ZN5doris10ForDecoderItE22seek_at_or_after_valueEPKvPb Unexecuted instantiation: _ZN5doris10ForDecoderIjE22seek_at_or_after_valueEPKvPb Unexecuted instantiation: _ZN5doris10ForDecoderImE22seek_at_or_after_valueEPKvPb Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE22seek_at_or_after_valueEPKvPb Unexecuted instantiation: _ZN5doris10ForDecoderIoE22seek_at_or_after_valueEPKvPb |
755 | | |
756 | | template class ForEncoder<int8_t>; |
757 | | template class ForEncoder<int16_t>; |
758 | | template class ForEncoder<int32_t>; |
759 | | template class ForEncoder<int64_t>; |
760 | | template class ForEncoder<int128_t>; |
761 | | template class ForEncoder<uint8_t>; |
762 | | template class ForEncoder<uint16_t>; |
763 | | template class ForEncoder<uint32_t>; |
764 | | template class ForEncoder<uint64_t>; |
765 | | template class ForEncoder<uint24_t>; |
766 | | template class ForEncoder<uint128_t>; |
767 | | |
768 | | template class ForDecoder<int8_t>; |
769 | | template class ForDecoder<int16_t>; |
770 | | template class ForDecoder<int32_t>; |
771 | | template class ForDecoder<int64_t>; |
772 | | template class ForDecoder<int128_t>; |
773 | | template class ForDecoder<uint8_t>; |
774 | | template class ForDecoder<uint16_t>; |
775 | | template class ForDecoder<uint32_t>; |
776 | | template class ForDecoder<uint64_t>; |
777 | | template class ForDecoder<uint24_t>; |
778 | | template class ForDecoder<uint128_t>; |
779 | | } // namespace doris |