Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
rle-benchmark.cc
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <iostream>
16 #include <sstream>
17 
18 #include "runtime/mem-pool.h"
19 #include "runtime/mem-tracker.h"
21 #include "util/benchmark.h"
23 #include "util/cpu-info.h"
24 
25 #include "common/names.h"
26 
27 // Benchmark to measure how quickly we can do bit encoding and decoding.
28 
29 // encode: Function Rate (iters/ms) Comparison
30 // ----------------------------------------------------------------------
31 // "BitWriter (8 byte) 1-Bit" 66.9 1X
32 // "BitWriter 1-Bit" 107.3 1.604X
33 // "BitWriter (8 byte) 2-Bit" 74.42 1X
34 // "BitWriter 2-Bit" 105.6 1.419X
35 // "BitWriter (8 byte) 3-Bit" 76.91 1X
36 // "BitWriter 3-Bit" 104 1.353X
37 // "BitWriter (8 byte) 4-Bit" 80.37 1X
38 // "BitWriter 4-Bit" 102.7 1.278X
39 // "BitWriter (8 byte) 5-Bit" 79.29 1X
40 // "BitWriter 5-Bit" 101 1.274X
41 // "BitWriter (8 byte) 6-Bit" 80.37 1X
42 // "BitWriter 6-Bit" 99.28 1.235X
43 // "BitWriter (8 byte) 7-Bit" 80.19 1X
44 // "BitWriter 7-Bit" 98.09 1.223X
45 // "BitWriter (8 byte) 8-Bit" 84.93 1X
46 // "BitWriter 8-Bit" 97 1.142X
47 // "BitWriter (8 byte) 9-Bit" 79.85 1X
48 // "BitWriter 9-Bit" 95.09 1.191X
49 // "BitWriter (8 byte) 10-Bit" 80.51 1X
50 // "BitWriter 10-Bit" 94.17 1.17X
51 // "BitWriter (8 byte) 11-Bit" 79.36 1X
52 // "BitWriter 11-Bit" 93.2 1.174X
53 // "BitWriter (8 byte) 12-Bit" 80.79 1X
54 // "BitWriter 12-Bit" 92.09 1.14X
55 // "BitWriter (8 byte) 13-Bit" 78.28 1X
56 // "BitWriter 13-Bit" 90.83 1.16X
57 // "BitWriter (8 byte) 14-Bit" 78.57 1X
58 // "BitWriter 14-Bit" 89.71 1.142X
59 // "BitWriter (8 byte) 15-Bit" 77.28 1X
60 // "BitWriter 15-Bit" 88 1.139X
61 // "BitWriter (8 byte) 16-Bit" 86.98 1X
62 // "BitWriter 16-Bit" 88.08 1.013X
63 
64 // decode: Function Rate (iters/ms) Comparison
65 // ----------------------------------------------------------------------
66 // "BitWriter (8 byte) 1-Bit" 132.9 1X
67 // "BitWriter 1-Bit" 126.9 0.9546X
68 // "BitWriter (8 byte) 2-Bit" 132.9 1X
69 // "BitWriter 2-Bit" 125.6 0.9448X
70 // "BitWriter (8 byte) 3-Bit" 132.8 1X
71 // "BitWriter 3-Bit" 122.7 0.9237X
72 // "BitWriter (8 byte) 4-Bit" 133.1 1X
73 // "BitWriter 4-Bit" 123.6 0.9284X
74 // "BitWriter (8 byte) 5-Bit" 132.2 1X
75 // "BitWriter 5-Bit" 118.2 0.8942X
76 // "BitWriter (8 byte) 6-Bit" 132.9 1X
77 // "BitWriter 6-Bit" 117.6 0.885X
78 // "BitWriter (8 byte) 7-Bit" 132.3 1X
79 // "BitWriter 7-Bit" 112.8 0.8525X
80 // "BitWriter (8 byte) 8-Bit" 132.9 1X
81 // "BitWriter 8-Bit" 119.2 0.8971X
82 // "BitWriter (8 byte) 9-Bit" 131.8 1X
83 // "BitWriter 9-Bit" 111.3 0.8447X
84 // "BitWriter (8 byte) 10-Bit" 131.4 1X
85 // "BitWriter 10-Bit" 108.5 0.8255X
86 // "BitWriter (8 byte) 11-Bit" 131.7 1X
87 // "BitWriter 11-Bit" 106.9 0.8118X
88 // "BitWriter (8 byte) 12-Bit" 132.9 1X
89 // "BitWriter 12-Bit" 108.8 0.8189X
90 // "BitWriter (8 byte) 13-Bit" 131 1X
91 // "BitWriter 13-Bit" 103.1 0.7873X
92 // "BitWriter (8 byte) 14-Bit" 131.6 1X
93 // "BitWriter 14-Bit" 101.6 0.7724X
94 // "BitWriter (8 byte) 15-Bit" 131.1 1X
95 // "BitWriter 15-Bit" 99.91 0.7622X
96 // "BitWriter (8 byte) 16-Bit" 133 1X
97 // "BitWriter 16-Bit" 105.2 0.7907X
98 
99 using namespace impala;
100 
101 const int BUFFER_LEN = 64 * 4096;
102 
103 struct TestData {
104  uint8_t* array;
105  uint8_t* buffer;
107  int num_bits;
110  bool result;
111 };
112 
113 void TestBitWriterEncode(int batch_size, void* d) {
114  TestData* data = reinterpret_cast<TestData*>(d);
115  int buffer_size = BitUtil::Ceil(data->num_bits * data->num_values, 8);
116  for (int i = 0; i < batch_size; ++i) {
117  BitWriter writer(data->buffer, buffer_size);
118  // Unroll this to focus more on Put performance.
119  for (int j = 0; j < data->num_values; j += 8) {
120  writer.PutValue(j + 0, data->num_bits);
121  writer.PutValue(j + 1, data->num_bits);
122  writer.PutValue(j + 2, data->num_bits);
123  writer.PutValue(j + 3, data->num_bits);
124  writer.PutValue(j + 4, data->num_bits);
125  writer.PutValue(j + 5, data->num_bits);
126  writer.PutValue(j + 6, data->num_bits);
127  writer.PutValue(j + 7, data->num_bits);
128  }
129  writer.Flush();
130  }
131 }
132 
133 void TestBitWriter8ByteEncode(int batch_size, void* d) {
134  TestData* data = reinterpret_cast<TestData*>(d);
135  int buffer_size = BitUtil::Ceil(data->num_bits * data->num_values, 8);
136  for (int i = 0; i < batch_size; ++i) {
137  BitWriter_8byte writer(data->buffer, buffer_size);
138  // Unroll this to focus more on Put performance.
139  for (int j = 0; j < data->num_values; j += 8) {
140  writer.PutValue(j + 0, data->num_bits);
141  writer.PutValue(j + 1, data->num_bits);
142  writer.PutValue(j + 2, data->num_bits);
143  writer.PutValue(j + 3, data->num_bits);
144  writer.PutValue(j + 4, data->num_bits);
145  writer.PutValue(j + 5, data->num_bits);
146  writer.PutValue(j + 6, data->num_bits);
147  writer.PutValue(j + 7, data->num_bits);
148  }
149  }
150 }
151 
152 void TestBitWriterDecode(int batch_size, void* d) {
153  TestData* data = reinterpret_cast<TestData*>(d);
154  int64_t v;
155  for (int i = 0; i < batch_size; ++i) {
156  BitReader reader(data->buffer, BUFFER_LEN);
157  // Unroll this to focus more on Put performance.
158  for (int j = 0; j < data->num_values; j += 8) {
159  reader.GetValue(data->num_bits, &v);
160  reader.GetValue(data->num_bits, &v);
161  reader.GetValue(data->num_bits, &v);
162  reader.GetValue(data->num_bits, &v);
163  reader.GetValue(data->num_bits, &v);
164  reader.GetValue(data->num_bits, &v);
165  reader.GetValue(data->num_bits, &v);
166  reader.GetValue(data->num_bits, &v);
167  }
168  }
169 }
170 
171 void TestBitWriter8ByteDecode(int batch_size, void* d) {
172  TestData* data = reinterpret_cast<TestData*>(d);
173  data->result = true;
174  int64_t v;
175  for (int i = 0; i < batch_size; ++i) {
176  BitReader_8byte reader(data->buffer, BUFFER_LEN);
177  // Unroll this to focus more on Put performance.
178  for (int j = 0; j < data->num_values; j += 8) {
179  data->result &= reader.GetValue(data->num_bits, &v);
180  data->result &= reader.GetValue(data->num_bits, &v);
181  data->result &= reader.GetValue(data->num_bits, &v);
182  data->result &= reader.GetValue(data->num_bits, &v);
183  data->result &= reader.GetValue(data->num_bits, &v);
184  data->result &= reader.GetValue(data->num_bits, &v);
185  data->result &= reader.GetValue(data->num_bits, &v);
186  data->result &= reader.GetValue(data->num_bits, &v);
187  }
188  }
189  CHECK(data->result);
190 }
191 
192 int main(int argc, char** argv) {
193  CpuInfo::Init();
194 
196  MemPool pool(&tracker);
197 
198  int num_values = 4096;
199  int max_bits = 16;
200 
201  Benchmark encode_suite("encode");
202  TestData data[max_bits];
203  for (int i = 0; i < max_bits; ++i) {
204  data[i].buffer = new uint8_t[BUFFER_LEN];
205  data[i].num_values = num_values;
206  data[i].num_bits = i + 1;
207  data[i].max_value = 1 << i;
208  data[i].pool = &pool;
209 
210  stringstream suffix;
211  suffix << " " << (i+1) << "-Bit";
212 
213  stringstream name;
214  name << "\"BitWriter (8 byte)" << suffix.str() << "\"";
215  int baseline =
216  encode_suite.AddBenchmark(name.str(), TestBitWriter8ByteEncode, &data[i], -1);
217 
218  name.str("");
219  name << "\"BitWriter" << suffix.str() << "\"";
220  encode_suite.AddBenchmark(name.str(), TestBitWriterEncode, &data[i], baseline);
221  }
222  cout << encode_suite.Measure() << endl;
223 
224  Benchmark decode_suite("decode");
225  for (int i = 0; i < max_bits; ++i) {
226  stringstream suffix;
227  suffix << " " << (i+1) << "-Bit";
228 
229  stringstream name;
230  name << "\"BitWriter (8 byte)" << suffix.str() << "\"";
231  int baseline =
232  decode_suite.AddBenchmark(name.str(), TestBitWriter8ByteDecode, &data[i], -1);
233 
234  name.str("");
235  name << "\"BitWriter" << suffix.str() << "\"";
236  decode_suite.AddBenchmark(name.str(), TestBitWriterDecode, &data[i], baseline);
237  }
238  cout << decode_suite.Measure() << endl;
239 
240  return 0;
241 }
bool PutValue(uint64_t v, int num_bits)
int AddBenchmark(const std::string &name, BenchmarkFunction fn, void *args, int baseline_idx=0)
Definition: benchmark.cc:70
MemTracker tracker
int main(int argc, char **argv)
void TestBitWriterDecode(int batch_size, void *d)
std::string Measure()
Runs all the benchmarks and returns the result in a formatted string.
Definition: benchmark.cc:83
MemPool * pool
void TestBitWriter8ByteDecode(int batch_size, void *d)
uint8_t * buffer
uint8_t * array
void TestBitWriterEncode(int batch_size, void *d)
bool GetValue(int num_bits, T *v)
ObjectPool pool
void Flush(bool align=false)
static int Ceil(int value, int divisor)
Returns the ceil of value/divisor.
Definition: bit-util.h:32
This class is thread-safe.
Definition: mem-tracker.h:61
void TestBitWriter8ByteEncode(int batch_size, void *d)
const int BUFFER_LEN
vector< Decimal > result
static void Init()
Initialize CpuInfo.
Definition: cpu-info.cc:75
string name
Definition: cpu-info.cc:50
bool PutValue(uint64_t v, int num_bits)
bool GetValue(int num_bits, T *v)