Skip to content
This repository was archived by the owner on May 9, 2024. It is now read-only.

Commit 2d2989f

Browse files
committed
Add bitmap generator benchmark
1 parent 8766c9b commit 2d2989f

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/**
2+
* Copyright 2023 Intel Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <benchmark/benchmark.h>
18+
#include <cstdlib>
19+
#include <memory>
20+
#include <random>
21+
#include <stdexcept>
22+
23+
#include "Logger/Logger.h"
24+
#include "ResultSet/BitmapGenerators.h"
25+
26+
size_t g_rand_seed = 42;
27+
28+
// percent_nulls is the percentage of time the distribution returns true, expressed in
29+
// decimal form (e.g. / 100)
30+
template <typename T>
31+
static std::unique_ptr<T[]> gen_data(size_t size, const T null_val, float percent_nulls) {
32+
auto data_buf = std::make_unique<T[]>(size);
33+
auto data_buf_ptr = data_buf.get();
34+
35+
std::mt19937 rand_gen(g_rand_seed);
36+
std::bernoulli_distribution dist(percent_nulls);
37+
for (size_t i = 0; i < size; i++) {
38+
if (dist(rand_gen)) {
39+
data_buf_ptr[i] = null_val;
40+
} else {
41+
data_buf_ptr[i] = i % std::numeric_limits<T>::max();
42+
}
43+
}
44+
45+
return data_buf;
46+
}
47+
48+
#include <iostream>
49+
50+
static auto alloc_bitmap(size_t input_sz) {
51+
// allocate extra space to ensure we can align
52+
size_t crt_sz = input_sz;
53+
constexpr size_t alignment = 64;
54+
if (crt_sz % alignment != 0) {
55+
crt_sz += (alignment - (crt_sz % alignment));
56+
}
57+
58+
void* bitmap_buf_ptr = std::aligned_alloc(alignment, crt_sz);
59+
auto bitmap_buf_owned = std::unique_ptr<char[], void (*)(char*)>(
60+
reinterpret_cast<char*>(bitmap_buf_ptr), [](char* ptr) { std::free(ptr); });
61+
return bitmap_buf_owned;
62+
}
63+
64+
// TODO: get null count and verify
65+
static void null_bitmap_8(benchmark::State& state) {
66+
// generate a 4096 element buffer with 25% nulls (+ a few more since the null sentinel
67+
// will match the max size in the buffer)
68+
const size_t num_elems = 4096;
69+
auto data_buf = gen_data<uint8_t>(num_elems, std::numeric_limits<uint8_t>::max(), 0.25);
70+
auto bitmap_ptr_owned = alloc_bitmap(ceil(num_elems / 8.));
71+
72+
auto initial_null_count =
73+
gen_null_bitmap_8(reinterpret_cast<uint8_t*>(bitmap_ptr_owned.get()),
74+
data_buf.get(),
75+
num_elems,
76+
std::numeric_limits<uint8_t>::max());
77+
78+
for (auto _ : state) {
79+
auto null_count =
80+
gen_null_bitmap_8(reinterpret_cast<uint8_t*>(bitmap_ptr_owned.get()),
81+
data_buf.get(),
82+
num_elems,
83+
/*null_value=*/std::numeric_limits<uint8_t>::max());
84+
CHECK_EQ(null_count, initial_null_count); // ensure null counts match
85+
}
86+
}
87+
88+
static void null_bitmap_16(benchmark::State& state) {
89+
// generate a 4096 element buffer with 25% nulls (+ a few more since the null sentinel
90+
// will match the max size in the buffer)
91+
const size_t num_elems = 4096;
92+
auto data_buf =
93+
gen_data<uint16_t>(num_elems, std::numeric_limits<uint16_t>::max(), 0.25);
94+
auto bitmap_ptr_owned = alloc_bitmap(ceil(num_elems / 8.));
95+
96+
auto initial_null_count =
97+
gen_null_bitmap_16(reinterpret_cast<uint8_t*>(bitmap_ptr_owned.get()),
98+
data_buf.get(),
99+
num_elems,
100+
/*null_value=*/std::numeric_limits<uint16_t>::max());
101+
102+
for (auto _ : state) {
103+
auto null_count =
104+
gen_null_bitmap_16(reinterpret_cast<uint8_t*>(bitmap_ptr_owned.get()),
105+
data_buf.get(),
106+
num_elems,
107+
/*null_value=*/std::numeric_limits<uint16_t>::max());
108+
CHECK_EQ(null_count, initial_null_count); // ensure null counts match
109+
}
110+
}
111+
112+
static void null_bitmap_32(benchmark::State& state) {
113+
// generate a 4096 element buffer with 25% nulls (+ a few more since the null sentinel
114+
// will match the max size in the buffer)
115+
const size_t num_elems = 4096;
116+
auto data_buf =
117+
gen_data<uint32_t>(num_elems, std::numeric_limits<uint32_t>::max(), 0.25);
118+
auto bitmap_ptr_owned = alloc_bitmap(ceil(num_elems / 8.));
119+
120+
auto initial_null_count =
121+
gen_null_bitmap_32(reinterpret_cast<uint8_t*>(bitmap_ptr_owned.get()),
122+
data_buf.get(),
123+
num_elems,
124+
/*null_value=*/std::numeric_limits<uint32_t>::max());
125+
126+
for (auto _ : state) {
127+
auto null_count =
128+
gen_null_bitmap_32(reinterpret_cast<uint8_t*>(bitmap_ptr_owned.get()),
129+
data_buf.get(),
130+
num_elems,
131+
/*null_value=*/std::numeric_limits<uint32_t>::max());
132+
CHECK_EQ(null_count, initial_null_count); // ensure null counts match
133+
}
134+
}
135+
136+
static void null_bitmap_64(benchmark::State& state) {
137+
// generate a 4096 element buffer with 25% nulls (+ a few more since the null sentinel
138+
// will match the max size in the buffer)
139+
const size_t num_elems = 4096;
140+
auto data_buf =
141+
gen_data<uint64_t>(num_elems, std::numeric_limits<uint64_t>::max(), 0.25);
142+
auto bitmap_ptr_owned = alloc_bitmap(ceil(num_elems / 8.));
143+
144+
auto initial_null_count =
145+
gen_null_bitmap_64(reinterpret_cast<uint8_t*>(bitmap_ptr_owned.get()),
146+
data_buf.get(),
147+
num_elems,
148+
/*null_value=*/std::numeric_limits<uint64_t>::max());
149+
150+
for (auto _ : state) {
151+
auto null_count =
152+
gen_null_bitmap_64(reinterpret_cast<uint8_t*>(bitmap_ptr_owned.get()),
153+
data_buf.get(),
154+
num_elems,
155+
/*null_value=*/std::numeric_limits<uint64_t>::max());
156+
CHECK_EQ(null_count, initial_null_count); // ensure null counts match
157+
}
158+
}
159+
160+
BENCHMARK(null_bitmap_8);
161+
BENCHMARK(null_bitmap_16);
162+
BENCHMARK(null_bitmap_32);
163+
BENCHMARK(null_bitmap_64);
164+
165+
BENCHMARK_MAIN();

omniscidb/Tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ endif()
5858

5959
# Tests + Microbenchmarks
6060
add_executable(StringDictionaryBenchmark StringDictionaryBenchmark.cpp)
61+
add_executable(BitmapGeneratorBenchmark BitmapGeneratorBenchmark.cpp ../ResultSet/BitmapGenerators.cpp)
6162

6263
if(ENABLE_L0)
6364
add_executable(L0MgrExecuteTest L0MgrExecuteTest.cpp)
@@ -134,6 +135,8 @@ else()
134135
target_link_libraries(StringDictionaryBenchmark benchmark gtest StringDictionary Logger Utils $<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.0>>:stdc++fs> ${CMAKE_DL_LIBS} ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
135136
endif()
136137

138+
target_link_libraries(BitmapGeneratorBenchmark benchmark)
139+
137140
if(ENABLE_CUDA)
138141
target_link_libraries(GpuSharedMemoryTest gtest Logger QueryEngine)
139142
endif()

0 commit comments

Comments
 (0)