Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
thread_scaling.bench.cpp
Go to the documentation of this file.
1
25
26#include <benchmark/benchmark.h>
27
29
30using namespace benchmark;
31
35
36namespace {
37
38constexpr size_t MSM_SIZE = 1 << 20;
39
40enum class Distribution { Clustered, UniformMixed, AllFull };
41
42class ThreadScalingBench : public benchmark::Fixture {
43 public:
46
47 void SetUp([[maybe_unused]] const ::benchmark::State& state) override
48 {
49 if (srs) {
50 return;
51 }
53 srs = bb::srs::get_crs_factory<Curve>()->get_crs(MSM_SIZE);
54 }
55
56 // 32-bit "small" value -- mimics witness indices, booleans, limbs.
57 // On BN254 (254-bit field) with ~14 bits per Pippenger slice, only the lowest
58 // ~2-3 rounds produce nonzero slices for these scalars; the rest get filtered.
59 Fr small_scalar() { return Fr(static_cast<uint64_t>(engine.get_random_uint32())); }
60 Fr full_scalar() { return Fr::random_element(&engine); }
61
62 std::vector<Fr> build_scalars(Distribution dist)
63 {
64 std::vector<Fr> scalars(MSM_SIZE);
65 switch (dist) {
66 case Distribution::Clustered:
67 for (size_t i = 0; i < MSM_SIZE / 2; ++i) {
68 scalars[i] = small_scalar();
69 }
70 for (size_t i = MSM_SIZE / 2; i < MSM_SIZE; ++i) {
71 scalars[i] = full_scalar();
72 }
73 break;
74 case Distribution::UniformMixed:
75 for (size_t i = 0; i < MSM_SIZE; ++i) {
76 scalars[i] = (engine.get_random_uint32() & 1U) ? small_scalar() : full_scalar();
77 }
78 break;
79 case Distribution::AllFull:
80 for (size_t i = 0; i < MSM_SIZE; ++i) {
81 scalars[i] = full_scalar();
82 }
83 break;
84 }
85 return scalars;
86 }
87};
88
89static void run_msm(ThreadScalingBench& fx, benchmark::State& state, Distribution dist)
90{
91 const size_t num_threads = static_cast<size_t>(state.range(0));
92
93 // Rebuild per-invocation of the bench is fine: scalars get mutated (Montgomery
94 // round-trip) inside batch_multi_scalar_mul, and we want consistent input across iterations.
95 std::vector<Fr> scalars = fx.build_scalars(dist);
96
97 std::vector<std::span<Fr>> scalar_spans;
99 scalar_spans.emplace_back(scalars);
100 point_spans.emplace_back(fx.srs->get_monomial_points().subspan(0, MSM_SIZE));
101
102 const size_t original_concurrency = bb::get_num_cpus();
104
105 for (auto _ : state) {
108 }
109
110 bb::set_parallel_for_concurrency(original_concurrency);
111}
112
113BENCHMARK_DEFINE_F(ThreadScalingBench, Clustered)(benchmark::State& state)
114{
115 run_msm(*this, state, Distribution::Clustered);
116}
117BENCHMARK_DEFINE_F(ThreadScalingBench, UniformMixed)(benchmark::State& state)
118{
119 run_msm(*this, state, Distribution::UniformMixed);
120}
121BENCHMARK_DEFINE_F(ThreadScalingBench, AllFull)(benchmark::State& state)
122{
123 run_msm(*this, state, Distribution::AllFull);
124}
125
126static void ThreadSweep(benchmark::internal::Benchmark* b)
127{
128 for (int64_t t : { 1, 2, 4, 8 }) {
129 b->Arg(t);
130 }
131}
132
133BENCHMARK_REGISTER_F(ThreadScalingBench, Clustered)->Unit(benchmark::kMillisecond)->Apply(ThreadSweep);
134BENCHMARK_REGISTER_F(ThreadScalingBench, UniformMixed)->Unit(benchmark::kMillisecond)->Apply(ThreadSweep);
135BENCHMARK_REGISTER_F(ThreadScalingBench, AllFull)->Unit(benchmark::kMillisecond)->Apply(ThreadSweep);
136
137} // namespace
138
typename Group::affine_element AffineElement
Definition bn254.hpp:22
bb::fr ScalarField
Definition bn254.hpp:18
static std::vector< AffineElement > batch_multi_scalar_mul(std::span< std::span< const AffineElement > > points, std::span< std::span< ScalarField > > scalars, bool handle_edge_cases=true) noexcept
Compute multiple MSMs in parallel with work balancing.
FF b
#define GOOGLE_BB_BENCH_REPORTER(state)
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:245
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
size_t get_num_cpus()
Definition thread.cpp:33
void set_parallel_for_concurrency(size_t num_cores)
Definition thread.cpp:23
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve::AffineElement G1
static field random_element(numeric::RNG *engine=nullptr) noexcept
BENCHMARK_MAIN()
Curve::ScalarField Fr