Skip to content

Commit 38bb221

Browse files
committed
Add extended benchmarks and unify bounds check macro
1 parent 30bf30b commit 38bb221

4 files changed

Lines changed: 87 additions & 15 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.21)
22
project(bitvector)
33

44
set(CMAKE_CXX_STANDARD 17)
5-
option(BV_BOUNDS_CHECK "Enable bounds checking in bitvector" OFF)
5+
option(BV_BOUNDS_CHECK "Enable bounds checking in bitvector" ON)
66
if(NOT BV_BOUNDS_CHECK)
7-
add_compile_definitions(BITVECTOR_DISABLE_BOUNDS_CHECK)
7+
add_compile_definitions(BITVECTOR_NO_BOUND_CHECK)
88
endif()
99
if(MSVC)
1010
# Set compiler flags for all configurations
@@ -34,11 +34,6 @@ elseif(MSVC)
3434
message(WARNING "BMI1 support is not available for MSVC in this configuration.")
3535
endif()
3636

37-
# Optionally disable bounds checking in the bitvector implementation
38-
option(BITVECTOR_ENABLE_BOUND_CHECK "Enable bounds checking in bitvector" OFF)
39-
if(NOT BITVECTOR_ENABLE_BOUND_CHECK)
40-
add_compile_definitions(BITVECTOR_NO_BOUND_CHECK)
41-
endif()
4237

4338
# Enable testing
4439
enable_testing()

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This repository provides a small bit vector implementation along with tests and
44

55
## Running the benchmarks without bounds checking
66

7-
Bounds checking is enabled by default. To benchmark without checks, configure and build with:
7+
Bounds checking is enabled by default. To benchmark without checks, configure and build with (this defines `BITVECTOR_NO_BOUND_CHECK`):
88

99
```bash
1010
cmake -S . -B build -DBV_BOUNDS_CHECK=OFF -DCMAKE_BUILD_TYPE=Release

bitvector_benchmark.cpp

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,87 @@ static void BM_Std_Access(benchmark::State& state) {
7272
}
7373
}
7474

75-
BENCHMARK(BM_Bowen_Set)->Arg(1<<20);
76-
BENCHMARK(BM_Std_Set)->Arg(1<<20);
77-
BENCHMARK(BM_Bowen_PushBack)->Arg(1<<20);
78-
BENCHMARK(BM_Std_PushBack)->Arg(1<<20);
79-
BENCHMARK(BM_Bowen_Access)->Arg(1<<20);
80-
BENCHMARK(BM_Std_Access)->Arg(1<<20);
75+
static void BM_Bowen_SetBitTrue6(benchmark::State& state) {
76+
size_t n = state.range(0);
77+
for (auto _ : state) {
78+
bitvector<> bv(n);
79+
for (size_t pos=0; pos+5 < n; pos+=6) {
80+
bv.set_bit_true_6(pos, 1);
81+
}
82+
benchmark::ClobberMemory();
83+
}
84+
}
85+
86+
static void BM_Std_SetBitTrue6(benchmark::State& state) {
87+
size_t n = state.range(0);
88+
for (auto _ : state) {
89+
std::vector<bool> bv(n);
90+
for (size_t pos=0; pos+5 < n; pos+=6) {
91+
for (int i=0;i<6;++i) {
92+
bv[pos+i] = true;
93+
}
94+
}
95+
benchmark::ClobberMemory();
96+
}
97+
}
98+
99+
static void BM_Bowen_QSetBitTrue6V2(benchmark::State& state) {
100+
size_t n = state.range(0);
101+
for (auto _ : state) {
102+
bitvector<> bv(n);
103+
bv.qset_bit_true_6_v2(0, 1, n);
104+
benchmark::ClobberMemory();
105+
}
106+
}
107+
108+
static void BM_Std_QSetBitTrue6(benchmark::State& state) {
109+
size_t n = state.range(0);
110+
for (auto _ : state) {
111+
std::vector<bool> bv(n);
112+
for (size_t i=0;i<n;++i) {
113+
bv[i] = true;
114+
}
115+
benchmark::ClobberMemory();
116+
}
117+
}
118+
119+
static void BM_Bowen_IncrementUntilZero(benchmark::State& state) {
120+
size_t n = state.range(0);
121+
bitvector<> bv(n, true);
122+
bv.set_bit(n-1, false);
123+
for (auto _ : state) {
124+
size_t pos = 0;
125+
bv.incrementUntilZero(pos);
126+
benchmark::DoNotOptimize(pos);
127+
}
128+
}
129+
130+
static void incrementUntilZeroStd(const std::vector<bool>& bv, size_t& pos) {
131+
while (pos < bv.size() && bv[pos]) ++pos;
132+
}
133+
134+
static void BM_Std_IncrementUntilZero(benchmark::State& state) {
135+
size_t n = state.range(0);
136+
std::vector<bool> bv(n, true);
137+
bv[n-1] = false;
138+
for (auto _ : state) {
139+
size_t pos = 0;
140+
incrementUntilZeroStd(bv, pos);
141+
benchmark::DoNotOptimize(pos);
142+
}
143+
}
144+
145+
BENCHMARK(BM_Bowen_Set)->Arg(1<<20)->MinTime(5.0);
146+
BENCHMARK(BM_Std_Set)->Arg(1<<20)->MinTime(5.0);
147+
BENCHMARK(BM_Bowen_PushBack)->Arg(1<<20)->MinTime(5.0);
148+
BENCHMARK(BM_Std_PushBack)->Arg(1<<20)->MinTime(5.0);
149+
BENCHMARK(BM_Bowen_Access)->Arg(1<<20)->MinTime(5.0);
150+
BENCHMARK(BM_Std_Access)->Arg(1<<20)->MinTime(5.0);
151+
BENCHMARK(BM_Bowen_SetBitTrue6)->Arg(1<<20)->MinTime(5.0);
152+
BENCHMARK(BM_Std_SetBitTrue6)->Arg(1<<20)->MinTime(5.0);
153+
BENCHMARK(BM_Bowen_QSetBitTrue6V2)->Arg(1<<20)->MinTime(5.0);
154+
BENCHMARK(BM_Std_QSetBitTrue6)->Arg(1<<20)->MinTime(5.0);
155+
BENCHMARK(BM_Bowen_IncrementUntilZero)->Arg(1<<20)->MinTime(5.0);
156+
BENCHMARK(BM_Std_IncrementUntilZero)->Arg(1<<20)->MinTime(5.0);
81157

82158
BENCHMARK_MAIN();

main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#include <chrono>
44
#include <iostream>
55
#include <vector>
6-
constexpr size_t SIZE = 1000000000; // 10 million elements
6+
// Benchmark size: 1 billion elements
7+
constexpr size_t SIZE = 1000000000;
78
// Benchmarks the performance of std::vector<bool> for setting, accessing, and traversing elements.
89
void benchmarkStdVectorBool(){
910

0 commit comments

Comments
 (0)