From 38bb22103a18cb15f9762a9b39756de0152385d9 Mon Sep 17 00:00:00 2001 From: Bowen Han Date: Sat, 7 Jun 2025 04:42:50 +0200 Subject: [PATCH 1/2] Add extended benchmarks and unify bounds check macro --- CMakeLists.txt | 9 +---- README.md | 2 +- bitvector_benchmark.cpp | 88 ++++++++++++++++++++++++++++++++++++++--- main.cpp | 3 +- 4 files changed, 87 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b1eb076..12284c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.21) project(bitvector) set(CMAKE_CXX_STANDARD 17) -option(BV_BOUNDS_CHECK "Enable bounds checking in bitvector" OFF) +option(BV_BOUNDS_CHECK "Enable bounds checking in bitvector" ON) if(NOT BV_BOUNDS_CHECK) - add_compile_definitions(BITVECTOR_DISABLE_BOUNDS_CHECK) + add_compile_definitions(BITVECTOR_NO_BOUND_CHECK) endif() if(MSVC) # Set compiler flags for all configurations @@ -34,11 +34,6 @@ elseif(MSVC) message(WARNING "BMI1 support is not available for MSVC in this configuration.") endif() -# Optionally disable bounds checking in the bitvector implementation -option(BITVECTOR_ENABLE_BOUND_CHECK "Enable bounds checking in bitvector" OFF) -if(NOT BITVECTOR_ENABLE_BOUND_CHECK) - add_compile_definitions(BITVECTOR_NO_BOUND_CHECK) -endif() # Enable testing enable_testing() diff --git a/README.md b/README.md index 11296f4..c29b6ad 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository provides a small bit vector implementation along with tests and ## Running the benchmarks without bounds checking -Bounds checking is enabled by default. To benchmark without checks, configure and build with: +Bounds checking is enabled by default. To benchmark without checks, configure and build with (this defines `BITVECTOR_NO_BOUND_CHECK`): ```bash cmake -S . -B build -DBV_BOUNDS_CHECK=OFF -DCMAKE_BUILD_TYPE=Release diff --git a/bitvector_benchmark.cpp b/bitvector_benchmark.cpp index cb83595..fa6fd64 100644 --- a/bitvector_benchmark.cpp +++ b/bitvector_benchmark.cpp @@ -72,11 +72,87 @@ static void BM_Std_Access(benchmark::State& state) { } } -BENCHMARK(BM_Bowen_Set)->Arg(1<<20); -BENCHMARK(BM_Std_Set)->Arg(1<<20); -BENCHMARK(BM_Bowen_PushBack)->Arg(1<<20); -BENCHMARK(BM_Std_PushBack)->Arg(1<<20); -BENCHMARK(BM_Bowen_Access)->Arg(1<<20); -BENCHMARK(BM_Std_Access)->Arg(1<<20); +static void BM_Bowen_SetBitTrue6(benchmark::State& state) { + size_t n = state.range(0); + for (auto _ : state) { + bitvector<> bv(n); + for (size_t pos=0; pos+5 < n; pos+=6) { + bv.set_bit_true_6(pos, 1); + } + benchmark::ClobberMemory(); + } +} + +static void BM_Std_SetBitTrue6(benchmark::State& state) { + size_t n = state.range(0); + for (auto _ : state) { + std::vector bv(n); + for (size_t pos=0; pos+5 < n; pos+=6) { + for (int i=0;i<6;++i) { + bv[pos+i] = true; + } + } + benchmark::ClobberMemory(); + } +} + +static void BM_Bowen_QSetBitTrue6V2(benchmark::State& state) { + size_t n = state.range(0); + for (auto _ : state) { + bitvector<> bv(n); + bv.qset_bit_true_6_v2(0, 1, n); + benchmark::ClobberMemory(); + } +} + +static void BM_Std_QSetBitTrue6(benchmark::State& state) { + size_t n = state.range(0); + for (auto _ : state) { + std::vector bv(n); + for (size_t i=0;i bv(n, true); + bv.set_bit(n-1, false); + for (auto _ : state) { + size_t pos = 0; + bv.incrementUntilZero(pos); + benchmark::DoNotOptimize(pos); + } +} + +static void incrementUntilZeroStd(const std::vector& bv, size_t& pos) { + while (pos < bv.size() && bv[pos]) ++pos; +} + +static void BM_Std_IncrementUntilZero(benchmark::State& state) { + size_t n = state.range(0); + std::vector bv(n, true); + bv[n-1] = false; + for (auto _ : state) { + size_t pos = 0; + incrementUntilZeroStd(bv, pos); + benchmark::DoNotOptimize(pos); + } +} + +BENCHMARK(BM_Bowen_Set)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Std_Set)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Bowen_PushBack)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Std_PushBack)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Bowen_Access)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Std_Access)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Bowen_SetBitTrue6)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Std_SetBitTrue6)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Bowen_QSetBitTrue6V2)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Std_QSetBitTrue6)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Bowen_IncrementUntilZero)->Arg(1<<20)->MinTime(5.0); +BENCHMARK(BM_Std_IncrementUntilZero)->Arg(1<<20)->MinTime(5.0); BENCHMARK_MAIN(); diff --git a/main.cpp b/main.cpp index e50f170..477f6e0 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,8 @@ #include #include #include -constexpr size_t SIZE = 1000000000; // 10 million elements +// Benchmark size: 1 billion elements +constexpr size_t SIZE = 1000000000; // Benchmarks the performance of std::vector for setting, accessing, and traversing elements. void benchmarkStdVectorBool(){ From 0ce975b335d62c9a4065341c1f2b09865d9ba263 Mon Sep 17 00:00:00 2001 From: Bowen Han Date: Sat, 7 Jun 2025 04:50:51 +0200 Subject: [PATCH 2/2] Merge latest main into work --- CMakeLists.txt | 5 +++-- README.md | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12284c6..f60a3c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.21) project(bitvector) set(CMAKE_CXX_STANDARD 17) -option(BV_BOUNDS_CHECK "Enable bounds checking in bitvector" ON) -if(NOT BV_BOUNDS_CHECK) +option(BITVECTOR_NO_BOUND_CHECK "Disable bounds checking in bitvector" OFF) +if(BITVECTOR_NO_BOUND_CHECK) add_compile_definitions(BITVECTOR_NO_BOUND_CHECK) endif() if(MSVC) @@ -34,6 +34,7 @@ elseif(MSVC) message(WARNING "BMI1 support is not available for MSVC in this configuration.") endif() +# Optionally disable bounds checking in the bitvector implementation # Enable testing enable_testing() diff --git a/README.md b/README.md index c29b6ad..04ed213 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This repository provides a small bit vector implementation along with tests and Bounds checking is enabled by default. To benchmark without checks, configure and build with (this defines `BITVECTOR_NO_BOUND_CHECK`): ```bash -cmake -S . -B build -DBV_BOUNDS_CHECK=OFF -DCMAKE_BUILD_TYPE=Release +cmake -S . -B build -DBITVECTOR_NO_BOUND_CHECK=ON -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release ./build/bitvector_benchmark ```