From ac3349a5f8e504deae708650260e273747a39c12 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 4 Nov 2025 17:39:07 +0300 Subject: [PATCH 01/20] Rank/Select Benchmarks with 10/90% fill --- src/benchmarks.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/src/benchmarks.cpp b/src/benchmarks.cpp index 25daaa8..3c51cf4 100644 --- a/src/benchmarks.cpp +++ b/src/benchmarks.cpp @@ -46,7 +46,7 @@ static void BM_SelectNonInterleaved(benchmark::State& state) { } pixie::BitVector bv(bits, n); - auto max_rank = bv.rank(bv.size()); + auto max_rank = bv.rank(bv.size()) + 1; for (auto _ : state) { uint64_t rank = rng() % max_rank; @@ -54,6 +54,87 @@ static void BM_SelectNonInterleaved(benchmark::State& state) { } } +static void BM_RankNonInterleaved10PercentFill(benchmark::State& state) { + size_t n = state.range(0); + std::mt19937_64 rng(42); + + std::vector bits(1 + n / 64); + size_t num_ones = n * 0.1; + for (int i = 0; i < num_ones; i++) { + uint64_t pos = rng() % n; + bits[pos / 64] |= (1ULL << pos % 64); + } + + pixie::BitVector bv(bits, n); + + for (auto _ : state) { + uint64_t pos = rng() % n; + benchmark::DoNotOptimize(bv.rank(pos)); + } +} + +static void BM_SelectNonInterleaved10PercentFill(benchmark::State& state) { + size_t n = state.range(0); + std::mt19937_64 rng(42); + + std::vector bits(1 + n / 64); + size_t num_ones = n * 0.1; + for (int i = 0; i < num_ones; i++) { + uint64_t pos = rng() % n; + bits[pos / 64] |= (1ULL << pos % 64); + } + + pixie::BitVector bv(bits, n); + + auto max_rank = bv.rank(bv.size()) + 1; + + for (auto _ : state) { + uint64_t rank = rng() % max_rank; + benchmark::DoNotOptimize(bv.select(rank)); + } +} + +static void BM_RankNonInterleaved90PercentFill(benchmark::State& state) { + size_t n = state.range(0); + std::mt19937_64 rng(42); + + std::vector bits(1 + n / 64); + size_t num_ones = n * 0.9; + for (int i = 0; i < num_ones; i++) { + uint64_t pos = rng() % n; + bits[pos / 64] |= (1ULL << pos % 64); + } + + pixie::BitVector bv(bits, n); + + for (auto _ : state) { + uint64_t pos = rng() % n; + benchmark::DoNotOptimize(bv.rank(pos)); + } +} + +static void BM_SelectNonInterleaved90PercentFill(benchmark::State& state) { + size_t n = state.range(0); + std::mt19937_64 rng(42); + + std::vector bits(1 + n / 64); + size_t num_ones = n * 0.9; + for (int i = 0; i < num_ones; i++) { + uint64_t pos = rng() % n; + bits[pos / 64] |= (1ULL << pos % 64); + } + + pixie::BitVector bv(bits, n); + + auto max_rank = bv.rank(bv.size()) + 1; + + for (auto _ : state) { + uint64_t rank = rng() % max_rank; + benchmark::DoNotOptimize(bv.select(rank)); + } +} + +/* BENCHMARK(BM_RankNonInterleaved) ->ArgNames({"n"}) ->RangeMultiplier(4) @@ -68,3 +149,27 @@ BENCHMARK(BM_SelectNonInterleaved) ->ArgNames({"n"}) ->RangeMultiplier(4) ->Range(8, 1ull << 34); +*/ +BENCHMARK(BM_RankNonInterleaved10PercentFill) + ->ArgNames({"n"}) + ->RangeMultiplier(4) + ->Range(8, 1ull << 34) + ->Iterations(100000); + +BENCHMARK(BM_SelectNonInterleaved10PercentFill) + ->ArgNames({"n"}) + ->RangeMultiplier(4) + ->Range(8, 1ull << 34) + ->Iterations(100000); + +BENCHMARK(BM_RankNonInterleaved90PercentFill) + ->ArgNames({"n"}) + ->RangeMultiplier(4) + ->Range(8, 1ull << 34) + ->Iterations(100000); + +BENCHMARK(BM_SelectNonInterleaved90PercentFill) + ->ArgNames({"n"}) + ->RangeMultiplier(4) + ->Range(8, 1ull << 34) + ->Iterations(100000); \ No newline at end of file From c0eef4b45a6b95ca29a140c6bc53b6c349129979 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 4 Nov 2025 17:40:30 +0300 Subject: [PATCH 02/20] Benchmark fix --- src/benchmarks.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/benchmarks.cpp b/src/benchmarks.cpp index 3c51cf4..e2f3734 100644 --- a/src/benchmarks.cpp +++ b/src/benchmarks.cpp @@ -134,7 +134,7 @@ static void BM_SelectNonInterleaved90PercentFill(benchmark::State& state) { } } -/* + BENCHMARK(BM_RankNonInterleaved) ->ArgNames({"n"}) ->RangeMultiplier(4) @@ -149,7 +149,7 @@ BENCHMARK(BM_SelectNonInterleaved) ->ArgNames({"n"}) ->RangeMultiplier(4) ->Range(8, 1ull << 34); -*/ + BENCHMARK(BM_RankNonInterleaved10PercentFill) ->ArgNames({"n"}) ->RangeMultiplier(4) From a02044e8596410a5b68ea64d4ccb42f5b9629991 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 20:21:56 +0300 Subject: [PATCH 03/20] Address Sanitizer flag, Disable AVX512 flag, messages --- CMakeLists.txt | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b520326..057f334 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,24 @@ cmake_minimum_required(VERSION 3.12) project(pixie) + set(MARCH "native" CACHE STRING "march compilier flag") set(CMAKE_CXX_FLAGS "-march=${MARCH}") +message(STATUS "MARCH is '${MARCH}'") + +option(USE_NO_AVX512 "Disable AVX512 instructions" OFF) +if(USE_NO_AVX512) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-avx512f") + message(STATUS "USE_NO_AVX512 is ON") +endif() + +option(ENABLE_ADDRESS_SANITIZER "Enable AddressSanitizer" OFF) +if(ENABLE_ADDRESS_SANITIZER) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") + set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fsanitize=address") + message(STATUS "AddressSanitizer is ON") +endif() + include(FetchContent) FetchContent_Declare( googletest @@ -45,4 +61,15 @@ target_link_libraries(unittests gtest gtest_main) +add_executable(benchmarkstests + src/benchmarkstests.cpp) +target_include_directories(benchmarkstests + PUBLIC include + PUBLIC ${GOOGLETEST_SOURCE_DIR}/include +) +set_property(TARGET benchmarkstests PROPERTY CXX_STANDARD 20) +target_link_libraries(benchmarkstests + gtest + gtest_main) + enable_testing() \ No newline at end of file From 506a93f162f5eca006619828c760dc4cb8e816ec Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 20:23:16 +0300 Subject: [PATCH 04/20] Becnhmarks iterations count --- src/benchmarks.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/benchmarks.cpp b/src/benchmarks.cpp index e2f3734..fd50201 100644 --- a/src/benchmarks.cpp +++ b/src/benchmarks.cpp @@ -138,17 +138,20 @@ static void BM_SelectNonInterleaved90PercentFill(benchmark::State& state) { BENCHMARK(BM_RankNonInterleaved) ->ArgNames({"n"}) ->RangeMultiplier(4) - ->Range(8, 1ull << 34); + ->Range(8, 1ull << 34) + ->Iterations(100000); BENCHMARK(BM_RankInterleaved) ->ArgNames({"n"}) ->RangeMultiplier(4) - ->Range(8, 1ull << 34); + ->Range(8, 1ull << 34) + ->Iterations(100000); BENCHMARK(BM_SelectNonInterleaved) ->ArgNames({"n"}) ->RangeMultiplier(4) - ->Range(8, 1ull << 34); + ->Range(8, 1ull << 34) + ->Iterations(100000); BENCHMARK(BM_RankNonInterleaved10PercentFill) ->ArgNames({"n"}) From 9cf0c438ae0b4491e08733ba64a81622623b2ce1 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 20:32:21 +0300 Subject: [PATCH 05/20] Rank512 test fix --- src/unittests.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/unittests.cpp b/src/unittests.cpp index bc0e038..534bb16 100644 --- a/src/unittests.cpp +++ b/src/unittests.cpp @@ -40,11 +40,13 @@ TEST(Rank512, Random) { a[i] = rng(); } size_t rank = 0; - for (size_t i = 0; i <= 512; ++i) { + for (size_t i = 0; i < 512; ++i) { auto p = rank_512(a.data(), i); ASSERT_EQ(p, rank); rank += 1 & (a[i >> 6] >> (i & 63)); } + auto p = rank_512(a.data(), 512); + ASSERT_EQ(p, rank); } } From e4e89ffeac3190362514cffe9e3085e4f82fd164 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 20:32:39 +0300 Subject: [PATCH 06/20] Benchmarks tests --- src/benchmarkstests.cpp | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/benchmarkstests.cpp diff --git a/src/benchmarkstests.cpp b/src/benchmarkstests.cpp new file mode 100644 index 0000000..a8c32dc --- /dev/null +++ b/src/benchmarkstests.cpp @@ -0,0 +1,72 @@ +#include + +#include +#include + +#include "bits.h" +#include "bitvector.h" + +using pixie::BitVector; +using pixie::BitVectorInterleaved; + + +TEST(BitVectorBenchmarkTest, SelectNonInterleaved10PercentFill) { + for (size_t n = 4; n <= (1ull << 34); n <<= 2) { + std::mt19937_64 rng(42); + + std::vector bits(1 + n / 64); + size_t num_ones = n * 0.1; + for (int i = 0; i < num_ones; i++) { + uint64_t pos = rng() % n; + bits[pos / 64] |= (1ULL << pos % 64); + } + + pixie::BitVector bv(bits, n); + + auto max_rank = bv.rank(bv.size()) + 1; + for (int i = 0; i < 100000; i++) { + uint64_t rank = rng() % max_rank; + bv.select(rank); + } + } +} + +TEST(BitVectorBenchmarkTest, SelectNonInterleaved90PercentFill) { + for (size_t n = 4; n <= (1ull << 34); n <<= 2) { + std::mt19937_64 rng(42); + + std::vector bits(1 + n / 64); + size_t num_ones = n * 0.9; + for (int i = 0; i < num_ones; i++) { + uint64_t pos = rng() % n; + bits[pos / 64] |= (1ULL << pos % 64); + } + + pixie::BitVector bv(bits, n); + + auto max_rank = bv.rank(bv.size()) + 1; + for (int i = 0; i < 100000; i++) { + uint64_t rank = rng() % max_rank; + bv.select(rank); + } + } +} + +TEST(BitVectorBenchmarkTest, SelectNonInterleaved) { + for (size_t n = 4; n <= (1ull << 34); n <<= 2) { + std::mt19937_64 rng(42); + + std::vector bits(1 + n / 64); + for (auto& x : bits) { + x = rng(); + } + pixie::BitVector bv(bits, n); + + auto max_rank = bv.rank(bv.size()) + 1; + + for (int i = 0; i < 100000; i++) { + uint64_t rank = rng() % max_rank; + bv.select(rank); + } + } +} \ No newline at end of file From 816e3304a7a26ff6cea374251d5494599189d42c Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 20:36:04 +0300 Subject: [PATCH 07/20] Changes detected using the address sanitizer --- include/bits.h | 6 ++---- include/bitvector.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/bits.h b/include/bits.h index 4f0bb25..8475efc 100644 --- a/include/bits.h +++ b/include/bits.h @@ -84,7 +84,7 @@ uint64_t rank_512(const uint64_t* x, uint64_t count) { #else - uint64_t last_uint = count >> 6; + uint64_t last_uint = count < 512 ? count >> 6 : 8; uint64_t pop_val = 0; @@ -92,9 +92,7 @@ uint64_t rank_512(const uint64_t* x, uint64_t count) { pop_val += std::popcount(x[i]); } - uint64_t final = x[last_uint] & first_bits_mask(count & 63); - - pop_val += std::popcount(final); + pop_val += count < 512 ? std::popcount(x[last_uint] & first_bits_mask(count & 63)) : 0; return pop_val; #endif diff --git a/include/bitvector.h b/include/bitvector.h index 8abf686..117e00a 100644 --- a/include/bitvector.h +++ b/include/bitvector.h @@ -355,7 +355,7 @@ class BitVectorInterleaved { offset_size_ -= num_bits; return result; } - uint64_t next = bits_[iterator_64_++]; + uint64_t next = iterator_64_ < bits_.size() ? bits_[iterator_64_++] : 0; result ^= (next & first_bits_mask(num_bits - offset_size_)) << offset_size_; offset_bits_ = (num_bits - offset_size_ == 64) From 96c4629130f82ec4ebb9d33564f30b5269af6d27 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 20:52:46 +0300 Subject: [PATCH 08/20] CI fix --- .github/workflows/build-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 48fdabc..72e0e03 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -1,4 +1,4 @@ -name: CMake Build and Test +name: CMake Build and Run Unittests on: push: @@ -18,7 +18,7 @@ jobs: - name: Configure CMake working-directory: ./build - run: cmake .. + run: cmake -DUSE_NO_AVX512=ON -DENABLE_ADDRESS_SANITIZER=ON .. - name: Build Project working-directory: ./build @@ -45,7 +45,7 @@ jobs: - name: Configure CMake working-directory: ./build - run: cmake .. -DMARCH=icelake-client + run: cmake -DENABLE_ADDRESS_SANITIZER=ON -DMARCH=icelake-client .. - name: Build Project working-directory: ./build From a5fd362bbea53294c22e0168de20b74909e1a10b Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 21:32:40 +0300 Subject: [PATCH 09/20] aligning bits span to the size of the basic block --- include/bitvector.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/bitvector.h b/include/bitvector.h index 117e00a..00e71bc 100644 --- a/include/bitvector.h +++ b/include/bitvector.h @@ -94,6 +94,8 @@ class BitVector { super_block_rank.resize(num_superblocks); basic_block_rank.resize(num_basicblocks); + bits.resize(((bits.size() + kBasicBlockSize - 1) / kBasicBlockSize) * kBasicBlockSize); + uint64_t super_block_sum = 0; uint16_t basic_block_sum = 0; From 6b0a0abba6497dc03e4984eb1095bdae6658a015 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 21:50:51 +0300 Subject: [PATCH 10/20] revert last commit --- include/bitvector.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/bitvector.h b/include/bitvector.h index 00e71bc..117e00a 100644 --- a/include/bitvector.h +++ b/include/bitvector.h @@ -94,8 +94,6 @@ class BitVector { super_block_rank.resize(num_superblocks); basic_block_rank.resize(num_basicblocks); - bits.resize(((bits.size() + kBasicBlockSize - 1) / kBasicBlockSize) * kBasicBlockSize); - uint64_t super_block_sum = 0; uint16_t basic_block_sum = 0; From bcb11435433ea3bcf88f1dbd49c76ebebea521d2 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 21:55:50 +0300 Subject: [PATCH 11/20] BitVector Basic test fix --- src/unittests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/unittests.cpp b/src/unittests.cpp index 534bb16..21f78e2 100644 --- a/src/unittests.cpp +++ b/src/unittests.cpp @@ -144,7 +144,8 @@ TEST(Select512, RankCompativility) { } TEST(BitVectorTest, Basic) { - std::vector bits = {0b101010101}; + std::vector bits(8, 0); + bits[0] = 0b101010101; BitVector bv(bits, 9); EXPECT_EQ(bv.size(), 9); EXPECT_EQ(bv[0], 1); From 05b7a7d28d4f504faae1b7c93eb9754154564182 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 22:08:19 +0300 Subject: [PATCH 12/20] CI with SDE fix --- .github/workflows/build-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 72e0e03..f974376 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -45,7 +45,7 @@ jobs: - name: Configure CMake working-directory: ./build - run: cmake -DENABLE_ADDRESS_SANITIZER=ON -DMARCH=icelake-client .. + run: cmake -DENABLE_ADDRESS_SANITIZER=ON -DMARCH=icelake-client -DHAVE_STD_REGEX=ON .. - name: Build Project working-directory: ./build From ed25418e39c62bcadb613d47d8fd8d679e06e4fb Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 22:23:59 +0300 Subject: [PATCH 13/20] Clang format --- include/bits.h | 4 +++- src/benchmarks.cpp | 3 +-- src/benchmarkstests.cpp | 5 ++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/bits.h b/include/bits.h index 8475efc..8537e0b 100644 --- a/include/bits.h +++ b/include/bits.h @@ -92,7 +92,9 @@ uint64_t rank_512(const uint64_t* x, uint64_t count) { pop_val += std::popcount(x[i]); } - pop_val += count < 512 ? std::popcount(x[last_uint] & first_bits_mask(count & 63)) : 0; + pop_val += count < 512 + ? std::popcount(x[last_uint] & first_bits_mask(count & 63)) + : 0; return pop_val; #endif diff --git a/src/benchmarks.cpp b/src/benchmarks.cpp index fd50201..7bc2533 100644 --- a/src/benchmarks.cpp +++ b/src/benchmarks.cpp @@ -134,7 +134,6 @@ static void BM_SelectNonInterleaved90PercentFill(benchmark::State& state) { } } - BENCHMARK(BM_RankNonInterleaved) ->ArgNames({"n"}) ->RangeMultiplier(4) @@ -175,4 +174,4 @@ BENCHMARK(BM_SelectNonInterleaved90PercentFill) ->ArgNames({"n"}) ->RangeMultiplier(4) ->Range(8, 1ull << 34) - ->Iterations(100000); \ No newline at end of file + ->Iterations(100000); diff --git a/src/benchmarkstests.cpp b/src/benchmarkstests.cpp index a8c32dc..1c9e738 100644 --- a/src/benchmarkstests.cpp +++ b/src/benchmarkstests.cpp @@ -9,7 +9,6 @@ using pixie::BitVector; using pixie::BitVectorInterleaved; - TEST(BitVectorBenchmarkTest, SelectNonInterleaved10PercentFill) { for (size_t n = 4; n <= (1ull << 34); n <<= 2) { std::mt19937_64 rng(42); @@ -67,6 +66,6 @@ TEST(BitVectorBenchmarkTest, SelectNonInterleaved) { for (int i = 0; i < 100000; i++) { uint64_t rank = rng() % max_rank; bv.select(rank); + } } - } -} \ No newline at end of file +} From eff4f59f8faf811e060b0c429443314cafaf7272 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 18 Nov 2025 22:29:49 +0300 Subject: [PATCH 14/20] aligning arrays to the size of the basic block int tests --- src/unittests.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/unittests.cpp b/src/unittests.cpp index 21f78e2..dddb0b7 100644 --- a/src/unittests.cpp +++ b/src/unittests.cpp @@ -160,7 +160,9 @@ TEST(BitVectorTest, Basic) { } TEST(BitVectorTest, MultipleWords) { - std::vector bits = {0xAAAAAAAAAAAAAAAA, 0x5555555555555555}; + std::vector bits(8, 0); + bits[0] = 0xAAAAAAAAAAAAAAAA; + bits[1] = 0x5555555555555555; BitVector bv(bits, 128); EXPECT_EQ(bv.size(), 128); @@ -176,13 +178,15 @@ TEST(BitVectorTest, MultipleWords) { } TEST(BitVectorTest, ToString) { - std::vector bits = {0b10101010101}; + std::vector bits(8, 0); + bits[0] = 0b10101010101; BitVector bv(bits, 11); EXPECT_EQ(bv.to_string(), "10101010101"); } TEST(BitVectorTest, RankBasic) { - std::vector bits = {0b10110}; + std::vector bits(8, 0); + bits[0] = 0b10110; BitVector bv(bits, 5); EXPECT_EQ(bv.rank(0), 0); // No bits @@ -194,7 +198,7 @@ TEST(BitVectorTest, RankBasic) { } TEST(BitVectorTest, RankWithZeros) { - std::vector bits = {0}; + std::vector bits(8, 0); BitVector bv(bits, 5); for (size_t i = 0; i <= 5; i++) { @@ -203,7 +207,8 @@ TEST(BitVectorTest, RankWithZeros) { } TEST(BitVectorTest, SelectBasic) { - std::vector bits = {0b1100010110010110}; + std::vector bits(8, 0); + bits[0] = 0b1100010110010110; BitVector bv(bits, 5); EXPECT_EQ(bv.select(1), 1); @@ -286,7 +291,7 @@ TEST(BitVectorInterleavedTest, MainTest) { } TEST(LowerBound4x64, Random) { - std::vector x(4); + std::vector x(8); std::mt19937_64 rng(42); for (size_t i = 0; i < 1000; i++) { uint64_t y = rng(); From c4ca136b456bf284f10285aa651a727966e08bbd Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 25 Nov 2025 14:09:56 +0300 Subject: [PATCH 15/20] refactoring --- .github/workflows/build-test.yml | 2 +- CMakeLists.txt | 16 ++++++++-------- src/{benchmarkstests.cpp => benchmark_tests.cpp} | 0 3 files changed, 9 insertions(+), 9 deletions(-) rename src/{benchmarkstests.cpp => benchmark_tests.cpp} (100%) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index f974376..e05a98c 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -18,7 +18,7 @@ jobs: - name: Configure CMake working-directory: ./build - run: cmake -DUSE_NO_AVX512=ON -DENABLE_ADDRESS_SANITIZER=ON .. + run: cmake -DDISABLE_AVX512=ON -DENABLE_ADDRESS_SANITIZER=ON .. - name: Build Project working-directory: ./build diff --git a/CMakeLists.txt b/CMakeLists.txt index 33c7600..935f6cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,10 +6,10 @@ set(MARCH "native" CACHE STRING "march compilier flag") set(CMAKE_CXX_FLAGS "-march=${MARCH}") message(STATUS "MARCH is '${MARCH}'") -option(USE_NO_AVX512 "Disable AVX512 instructions" OFF) -if(USE_NO_AVX512) +option(DISABLE_AVX512 "Disable AVX512 instructions" OFF) +if(DISABLE_AVX512) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-avx512f") - message(STATUS "USE_NO_AVX512 is ON") + message(STATUS "DISABLE_AVX512 is ON") endif() option(ENABLE_ADDRESS_SANITIZER "Enable AddressSanitizer" OFF) @@ -61,14 +61,14 @@ target_link_libraries(unittests gtest gtest_main) -add_executable(benchmarkstests - src/benchmarkstests.cpp) -target_include_directories(benchmarkstests +add_executable(benchmark_tests + src/benchmark_tests.cpp) +target_include_directories(benchmark_tests PUBLIC include PUBLIC ${GOOGLETEST_SOURCE_DIR}/include ) -set_property(TARGET benchmarkstests PROPERTY CXX_STANDARD 20) -target_link_libraries(benchmarkstests +set_property(TARGET benchmark_tests PROPERTY CXX_STANDARD 20) +target_link_libraries(benchmark_tests gtest gtest_main) diff --git a/src/benchmarkstests.cpp b/src/benchmark_tests.cpp similarity index 100% rename from src/benchmarkstests.cpp rename to src/benchmark_tests.cpp From 7de5bbad0581729a7947e4ed0f942d3609e208eb Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 25 Nov 2025 14:55:30 +0300 Subject: [PATCH 16/20] CI for benchmark_tests --- .github/workflows/benchmarks-test.yml | 54 +++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/benchmarks-test.yml diff --git a/.github/workflows/benchmarks-test.yml b/.github/workflows/benchmarks-test.yml new file mode 100644 index 0000000..77fa585 --- /dev/null +++ b/.github/workflows/benchmarks-test.yml @@ -0,0 +1,54 @@ +name: CMake Build and Run Benchmark Tests + +on: + schedule: + - cron: '0 12 * * *' + +jobs: + build-and-test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Create Build Directory + run: mkdir build + + - name: Configure CMake + working-directory: ./build + run: cmake -DDISABLE_AVX512=ON -DENABLE_ADDRESS_SANITIZER=ON .. + + - name: Build Project + working-directory: ./build + run: make -j + + - name: Run Benchmark Tests + working-directory: ./build + run: ./benchmark_tests + + build-and-test-with-SDE: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Create Build Directory + run: mkdir build + + - name: Download and Unpack SDE + working-directory: ./build + run: | + wget https://downloadmirror.intel.com/859732/sde-external-9.58.0-2025-06-16-lin.tar.xz + tar xf sde-external-9.58.0-2025-06-16-lin.tar.xz + + - name: Configure CMake + working-directory: ./build + run: cmake -DENABLE_ADDRESS_SANITIZER=ON -DMARCH=icelake-client -DHAVE_STD_REGEX=ON .. + + - name: Build Project + working-directory: ./build + run: make -j + + - name: Run Benchmark Tests + working-directory: ./build + run: sde-external-9.58.0-2025-06-16-lin/sde64 -icl -emu-xinuse 0 -- ./benchmark_tests \ No newline at end of file From 6f13a9191b3ac20b6b8da9cd7b12e7e650650ece Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 25 Nov 2025 14:59:19 +0300 Subject: [PATCH 17/20] CI fix --- .github/workflows/benchmarks-test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks-test.yml b/.github/workflows/benchmarks-test.yml index 77fa585..01f2b5a 100644 --- a/.github/workflows/benchmarks-test.yml +++ b/.github/workflows/benchmarks-test.yml @@ -2,7 +2,9 @@ name: CMake Build and Run Benchmark Tests on: schedule: - - cron: '0 12 * * *' + - cron: '0 0 * * *' + + workflow_dispatch: jobs: build-and-test: From 31740707fc688c60c5a2ee95c4d8b2bfd82a6a46 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 25 Nov 2025 15:10:42 +0300 Subject: [PATCH 18/20] Temporary CI fix --- .github/workflows/benchmarks-test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/benchmarks-test.yml b/.github/workflows/benchmarks-test.yml index 01f2b5a..106657e 100644 --- a/.github/workflows/benchmarks-test.yml +++ b/.github/workflows/benchmarks-test.yml @@ -5,6 +5,8 @@ on: - cron: '0 0 * * *' workflow_dispatch: + + push: jobs: build-and-test: From 7ad7b676c52c544435b0b1b77df9c50e56a78389 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 25 Nov 2025 15:17:50 +0300 Subject: [PATCH 19/20] Benchmark fix (the array size must be a multiple of 8) --- src/benchmark_tests.cpp | 6 +++--- src/benchmarks.cpp | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/benchmark_tests.cpp b/src/benchmark_tests.cpp index 1c9e738..1233a3c 100644 --- a/src/benchmark_tests.cpp +++ b/src/benchmark_tests.cpp @@ -13,7 +13,7 @@ TEST(BitVectorBenchmarkTest, SelectNonInterleaved10PercentFill) { for (size_t n = 4; n <= (1ull << 34); n <<= 2) { std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); size_t num_ones = n * 0.1; for (int i = 0; i < num_ones; i++) { uint64_t pos = rng() % n; @@ -34,7 +34,7 @@ TEST(BitVectorBenchmarkTest, SelectNonInterleaved90PercentFill) { for (size_t n = 4; n <= (1ull << 34); n <<= 2) { std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); size_t num_ones = n * 0.9; for (int i = 0; i < num_ones; i++) { uint64_t pos = rng() % n; @@ -55,7 +55,7 @@ TEST(BitVectorBenchmarkTest, SelectNonInterleaved) { for (size_t n = 4; n <= (1ull << 34); n <<= 2) { std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); for (auto& x : bits) { x = rng(); } diff --git a/src/benchmarks.cpp b/src/benchmarks.cpp index 7bc2533..3bf3b66 100644 --- a/src/benchmarks.cpp +++ b/src/benchmarks.cpp @@ -8,7 +8,7 @@ static void BM_RankNonInterleaved(benchmark::State& state) { size_t n = state.range(0); std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); for (auto& x : bits) { x = rng(); } @@ -24,7 +24,7 @@ static void BM_RankInterleaved(benchmark::State& state) { size_t n = state.range(0); std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); for (auto& x : bits) { x = rng(); } @@ -40,7 +40,7 @@ static void BM_SelectNonInterleaved(benchmark::State& state) { size_t n = state.range(0); std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); for (auto& x : bits) { x = rng(); } @@ -58,7 +58,7 @@ static void BM_RankNonInterleaved10PercentFill(benchmark::State& state) { size_t n = state.range(0); std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); size_t num_ones = n * 0.1; for (int i = 0; i < num_ones; i++) { uint64_t pos = rng() % n; @@ -77,7 +77,7 @@ static void BM_SelectNonInterleaved10PercentFill(benchmark::State& state) { size_t n = state.range(0); std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); size_t num_ones = n * 0.1; for (int i = 0; i < num_ones; i++) { uint64_t pos = rng() % n; @@ -98,7 +98,7 @@ static void BM_RankNonInterleaved90PercentFill(benchmark::State& state) { size_t n = state.range(0); std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); size_t num_ones = n * 0.9; for (int i = 0; i < num_ones; i++) { uint64_t pos = rng() % n; @@ -117,7 +117,7 @@ static void BM_SelectNonInterleaved90PercentFill(benchmark::State& state) { size_t n = state.range(0); std::mt19937_64 rng(42); - std::vector bits(1 + n / 64); + std::vector bits(((8 + n / 64) / 8) * 8); size_t num_ones = n * 0.9; for (int i = 0; i < num_ones; i++) { uint64_t pos = rng() % n; From 06b4d3f74790e792d76496189d43a6a3017e4448 Mon Sep 17 00:00:00 2001 From: mperikov Date: Tue, 25 Nov 2025 15:32:08 +0300 Subject: [PATCH 20/20] CI 'on' fix --- .github/workflows/benchmarks-test.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/benchmarks-test.yml b/.github/workflows/benchmarks-test.yml index 106657e..c957c0c 100644 --- a/.github/workflows/benchmarks-test.yml +++ b/.github/workflows/benchmarks-test.yml @@ -1,12 +1,10 @@ name: CMake Build and Run Benchmark Tests on: - schedule: - - cron: '0 0 * * *' - - workflow_dispatch: - push: + branches: [ main ] + pull_request: + branches: [ main ] jobs: build-and-test: