From 579012e6b282706f6869206d6461fccb09a0baa5 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Fri, 26 Sep 2025 10:22:56 +0300 Subject: [PATCH 1/3] Fuse functions --- benchmarks/inc/utility.hpp | 20 +++++++++----------- benchmarks/src/vector_bool_copy.cpp | 14 +++++++------- benchmarks/src/vector_bool_copy_n.cpp | 14 +++++++------- benchmarks/src/vector_bool_count.cpp | 2 +- benchmarks/src/vector_bool_move.cpp | 14 +++++++------- 5 files changed, 31 insertions(+), 33 deletions(-) diff --git a/benchmarks/inc/utility.hpp b/benchmarks/inc/utility.hpp index d1d3f06e84c..4ab5fabc3de 100644 --- a/benchmarks/inc/utility.hpp +++ b/benchmarks/inc/utility.hpp @@ -7,30 +7,28 @@ #include #include #include +#include #include template class Alloc = std::allocator> std::vector> random_vector(size_t n) { - std::mt19937_64 prng; - std::vector> res(n); + if constexpr (std::is_same_v) { + std::mt19937 gen; + std::bernoulli_distribution dist{0.5}; + std::generate(res.begin(), res.end(), [&] { return dist(gen); }); + } else { + std::mt19937_64 prng; // Here, the type Contained can be char, int, aggregate, or non_trivial where Data is char or int. // (aggregate and non_trivial are defined in udt.hpp.) // static_cast silences truncation warnings when Contained is directly char or int, // but is insufficient for aggregate or non_trivial. #pragma warning(push) #pragma warning(disable : 4244) // warning C4244: conversion from 'uint64_t' to 'Data', possible loss of data - std::generate(res.begin(), res.end(), [&prng] { return static_cast(prng()); }); + std::generate(res.begin(), res.end(), [&prng] { return static_cast(prng()); }); #pragma warning(pop) + } return res; } - -std::vector random_bool_vector(const size_t size) { - std::mt19937 gen; - std::bernoulli_distribution dist{0.5}; - std::vector result(size); - std::generate(result.begin(), result.end(), [&] { return dist(gen); }); - return result; -} diff --git a/benchmarks/src/vector_bool_copy.cpp b/benchmarks/src/vector_bool_copy.cpp index 9f9ed1283f2..9c7bb5827d1 100644 --- a/benchmarks/src/vector_bool_copy.cpp +++ b/benchmarks/src/vector_bool_copy.cpp @@ -14,7 +14,7 @@ using namespace std; void copy_block_aligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -26,7 +26,7 @@ void copy_block_aligned(benchmark::State& state) { void copy_source_misaligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -38,7 +38,7 @@ void copy_source_misaligned(benchmark::State& state) { void copy_dest_misaligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -51,7 +51,7 @@ void copy_dest_misaligned(benchmark::State& state) { // Special benchmark for matching char alignment void copy_matching_alignment(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -63,7 +63,7 @@ void copy_matching_alignment(benchmark::State& state) { // Special benchmarks for single block corner case void copy_both_single_blocks(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; @@ -75,7 +75,7 @@ void copy_both_single_blocks(benchmark::State& state) { } void copy_source_single_block(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; @@ -87,7 +87,7 @@ void copy_source_single_block(benchmark::State& state) { } void copy_dest_single_block(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; diff --git a/benchmarks/src/vector_bool_copy_n.cpp b/benchmarks/src/vector_bool_copy_n.cpp index 860e43a041c..2ade38c90f4 100644 --- a/benchmarks/src/vector_bool_copy_n.cpp +++ b/benchmarks/src/vector_bool_copy_n.cpp @@ -14,7 +14,7 @@ using namespace std; void copy_n_block_aligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -26,7 +26,7 @@ void copy_n_block_aligned(benchmark::State& state) { void copy_n_source_misaligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -38,7 +38,7 @@ void copy_n_source_misaligned(benchmark::State& state) { void copy_n_dest_misaligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -51,7 +51,7 @@ void copy_n_dest_misaligned(benchmark::State& state) { // Special benchmark for matching char alignment void copy_n_matching_alignment(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -63,7 +63,7 @@ void copy_n_matching_alignment(benchmark::State& state) { // Special benchmarks for single block corner case void copy_n_both_single_blocks(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; @@ -75,7 +75,7 @@ void copy_n_both_single_blocks(benchmark::State& state) { } void copy_n_source_single_block(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; @@ -87,7 +87,7 @@ void copy_n_source_single_block(benchmark::State& state) { } void copy_n_dest_single_block(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; diff --git a/benchmarks/src/vector_bool_count.cpp b/benchmarks/src/vector_bool_count.cpp index 93e723dcf57..65ad7fb9b91 100644 --- a/benchmarks/src/vector_bool_count.cpp +++ b/benchmarks/src/vector_bool_count.cpp @@ -14,7 +14,7 @@ using namespace std; void count_aligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector v = random_bool_vector(size); + vector v = random_vector(size); bool b = false; diff --git a/benchmarks/src/vector_bool_move.cpp b/benchmarks/src/vector_bool_move.cpp index e0193e52a3e..a8c3e693616 100644 --- a/benchmarks/src/vector_bool_move.cpp +++ b/benchmarks/src/vector_bool_move.cpp @@ -14,7 +14,7 @@ using namespace std; void move_block_aligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -26,7 +26,7 @@ void move_block_aligned(benchmark::State& state) { void move_source_misaligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -38,7 +38,7 @@ void move_source_misaligned(benchmark::State& state) { void move_dest_misaligned(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -51,7 +51,7 @@ void move_dest_misaligned(benchmark::State& state) { // Special benchmark for matching char alignment void move_matching_alignment(benchmark::State& state) { const auto size = static_cast(state.range(0)); - vector source = random_bool_vector(size); + vector source = random_vector(size); vector dest(size, false); for (auto _ : state) { @@ -63,7 +63,7 @@ void move_matching_alignment(benchmark::State& state) { // Special benchmarks for single block corner case void move_both_single_blocks(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; @@ -75,7 +75,7 @@ void move_both_single_blocks(benchmark::State& state) { } void move_source_single_block(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; @@ -87,7 +87,7 @@ void move_source_single_block(benchmark::State& state) { } void move_dest_single_block(benchmark::State& state) { - vector source = random_bool_vector(50); + vector source = random_vector(50); vector dest(50, false); const size_t length = 20; From fa045e149a8b7bbb48ea4da5e291c3f259abe3fb Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Fri, 26 Sep 2025 10:42:51 +0300 Subject: [PATCH 2/3] Optimize bool branch too for consistency --- benchmarks/inc/utility.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/benchmarks/inc/utility.hpp b/benchmarks/inc/utility.hpp index 4ab5fabc3de..ea5fb842ebe 100644 --- a/benchmarks/inc/utility.hpp +++ b/benchmarks/inc/utility.hpp @@ -15,9 +15,8 @@ std::vector> random_vector(size_t n) { std::vector> res(n); if constexpr (std::is_same_v) { - std::mt19937 gen; - std::bernoulli_distribution dist{0.5}; - std::generate(res.begin(), res.end(), [&] { return dist(gen); }); + std::mt19937 prng; + std::generate(res.begin(), res.end(), [&prng] { return static_cast(prng() & 1); }); } else { std::mt19937_64 prng; // Here, the type Contained can be char, int, aggregate, or non_trivial where Data is char or int. From 2f3b5e3fbd5a31bab8cc05851b347f822446787d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 26 Sep 2025 11:06:05 -0700 Subject: [PATCH 3/3] All shall love mt19937_64 and despair. --- benchmarks/inc/utility.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/benchmarks/inc/utility.hpp b/benchmarks/inc/utility.hpp index ea5fb842ebe..a8f9eda29a5 100644 --- a/benchmarks/inc/utility.hpp +++ b/benchmarks/inc/utility.hpp @@ -13,12 +13,11 @@ template class Alloc = std::allocator> std::vector> random_vector(size_t n) { std::vector> res(n); + std::mt19937_64 prng; if constexpr (std::is_same_v) { - std::mt19937 prng; std::generate(res.begin(), res.end(), [&prng] { return static_cast(prng() & 1); }); } else { - std::mt19937_64 prng; // Here, the type Contained can be char, int, aggregate, or non_trivial where Data is char or int. // (aggregate and non_trivial are defined in udt.hpp.) // static_cast silences truncation warnings when Contained is directly char or int,