Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
basics.bench.cpp
Go to the documentation of this file.
1
30#include <benchmark/benchmark.h>
31
32using namespace benchmark;
33using namespace bb;
34namespace {
35using Curve = curve::BN254;
37#define MAX_REPETITION_LOG 12
38
46void parallel_for_field_element_addition(State& state)
47{
49 size_t num_cpus = get_num_cpus();
50 std::vector<std::vector<Fr>> copy_vector(num_cpus);
51 for (size_t i = 0; i < num_cpus; i++) {
52 for (size_t j = 0; j < 2; j++) {
53 copy_vector[i].emplace_back(Fr::random_element(&engine));
54 copy_vector[i].emplace_back(Fr::random_element(&engine));
55 }
56 }
57 for (auto _ : state) {
58 state.PauseTiming();
59 size_t num_external_cycles = 1 << static_cast<size_t>(state.range(0));
60 size_t num_internal_cycles = 1 << (MAX_REPETITION_LOG - static_cast<size_t>(state.range(0)));
61 state.ResumeTiming();
62 for (size_t i = 0; i < num_external_cycles; i++) {
63 parallel_for(num_cpus, [num_internal_cycles, &copy_vector](size_t index) {
64 for (size_t i = 0; i < num_internal_cycles; i++) {
65 copy_vector[index][i & 1] += copy_vector[index][1 - (i & 1)];
66 }
67 });
68 }
69 }
70}
71
78void ff_addition(State& state)
79{
81 std::vector<Fr> copy_vector(2);
82 for (size_t j = 0; j < 2; j++) {
83 copy_vector.emplace_back(Fr::random_element(&engine));
84 copy_vector.emplace_back(Fr::random_element(&engine));
85 }
86
87 for (auto _ : state) {
88 state.PauseTiming();
89 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
90 state.ResumeTiming();
91 for (size_t i = 0; i < num_cycles; i++) {
92 copy_vector[i & 1] += copy_vector[1 - (i & 1)];
93 }
94 }
95}
96
103void ff_multiplication(State& state)
104{
106 std::vector<Fr> copy_vector(2);
107 for (size_t j = 0; j < 2; j++) {
108 copy_vector.emplace_back(Fr::random_element(&engine));
109 copy_vector.emplace_back(Fr::random_element(&engine));
110 }
111
112 for (auto _ : state) {
113 state.PauseTiming();
114 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
115 state.ResumeTiming();
116 for (size_t i = 0; i < num_cycles; i++) {
117 copy_vector[i & 1] *= copy_vector[1 - (i & 1)];
118 }
119 }
120}
121
128void ff_sqr(State& state)
129{
131 std::vector<Fr> copy_vector(2);
132 for (size_t j = 0; j < 2; j++) {
133 copy_vector.emplace_back(Fr::random_element(&engine));
134 copy_vector.emplace_back(Fr::random_element(&engine));
135 }
136
137 for (auto _ : state) {
138 state.PauseTiming();
139 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
140 state.ResumeTiming();
141 for (size_t i = 0; i < num_cycles; i++) {
142 copy_vector[0] = copy_vector[0].sqr();
143 }
144 }
145}
146
153void ff_invert(State& state)
154{
157
158 for (auto _ : state) {
159 state.PauseTiming();
160 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
161 state.ResumeTiming();
162 for (size_t i = 0; i < num_cycles; i++) {
163 element = (element + Fr::one()).invert();
164 }
165 }
166}
167
174void ff_to_montgomery(State& state)
175{
178
179 for (auto _ : state) {
180 state.PauseTiming();
181 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
182 state.ResumeTiming();
183 for (size_t i = 0; i < num_cycles; i++) {
184 element = element.to_montgomery_form();
185 }
186 }
187}
194void ff_from_montgomery(State& state)
195{
198
199 for (auto _ : state) {
200 state.PauseTiming();
201 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
202 state.ResumeTiming();
203 for (size_t i = 0; i < num_cycles; i++) {
204 element = element.from_montgomery_form();
205 }
206 }
207}
208
215void ff_reduce(State& state)
216{
219
220 for (auto _ : state) {
221 state.PauseTiming();
222 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
223 state.ResumeTiming();
224 for (size_t i = 0; i < num_cycles; i++) {
225 element = (element + element).reduce_once();
226 }
227 }
228}
229
236void projective_point_addition(State& state)
237{
239 std::vector<Curve::Element> copy_vector(2);
240 for (size_t j = 0; j < 2; j++) {
241 copy_vector.emplace_back(Curve::Element::random_element(&engine));
242 copy_vector.emplace_back(Curve::Element::random_element(&engine));
243 }
244
245 for (auto _ : state) {
246 state.PauseTiming();
247 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
248 state.ResumeTiming();
249 for (size_t i = 0; i < num_cycles; i++) {
250 copy_vector[i & 1] += copy_vector[1 - (i & 1)];
251 }
252 }
253}
254
261void projective_point_accidental_doubling(State& state)
262{
264 std::vector<Curve::Element> copy_vector(2);
265 for (size_t j = 0; j < 2; j++) {
266 copy_vector.emplace_back(Curve::Element::random_element(&engine));
267 copy_vector.emplace_back(Curve::Element::random_element(&engine));
268 }
269
270 for (auto _ : state) {
271 state.PauseTiming();
272 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
273 state.ResumeTiming();
274 for (size_t i = 0; i < num_cycles; i++) {
275 copy_vector[0] += copy_vector[0];
276 }
277 }
278}
279
286void projective_point_doubling(State& state)
287{
289 std::vector<Curve::Element> copy_vector(2);
290 for (size_t j = 0; j < 2; j++) {
291 copy_vector.emplace_back(Curve::Element::random_element(&engine));
292 copy_vector.emplace_back(Curve::Element::random_element(&engine));
293 }
294
295 for (auto _ : state) {
296 state.PauseTiming();
297 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
298 state.ResumeTiming();
299 for (size_t i = 0; i < num_cycles; i++) {
300 copy_vector[0] = copy_vector[0].dbl();
301 }
302 }
303}
304
311void scalar_multiplication_bench(State& state)
312{
314 Curve::Element element = Curve::Element::random_element(&engine);
315 Fr scalar = Fr::random_element(&engine);
316
317 for (auto _ : state) {
318 state.PauseTiming();
319 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
320 state.ResumeTiming();
321 for (size_t i = 0; i < num_cycles; i++) {
322 element = element * scalar;
323 scalar += scalar;
324 }
325 }
326}
333void cycle_waste(State& state)
334{
335
336 for (auto _ : state) {
337 state.PauseTiming();
338 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
339 state.ResumeTiming();
340 for (volatile size_t i = 0; i < num_cycles;) {
341 i = i + 1;
342 }
343 }
344}
345
352void sequential_copy(State& state)
353{
354
356 for (auto _ : state) {
357 state.PauseTiming();
358 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
359 std::vector<Fr> input(num_cycles);
360 for (size_t i = 0; i < num_cycles; i++) {
361 *(uint256_t*)&input[i] = engine.get_random_uint256();
362 }
363 std::vector<Fr> output(num_cycles);
364
365 state.ResumeTiming();
366 for (size_t i = 0; i < num_cycles; i++) {
367 output[i] = input[i];
368 }
369 }
370}
371
377void uint_multiplication(State& state)
378{
380 std::vector<uint256_t> copy_vector(2);
381 for (size_t j = 0; j < 2; j++) {
382 copy_vector.emplace_back(engine.get_random_uint256());
383 copy_vector.emplace_back(engine.get_random_uint256());
384 copy_vector[0] += (1 - copy_vector[0].get_bit(0));
385 copy_vector[1] += (1 - copy_vector[1].get_bit(0));
386 }
387
388 for (auto _ : state) {
389 state.PauseTiming();
390 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
391 state.ResumeTiming();
392 for (size_t i = 0; i < num_cycles; i++) {
393 copy_vector[i & 1] *= copy_vector[1 - (i & 1)];
394 }
395 }
396}
397
403void uint_extended_multiplication(State& state)
404{
406 std::vector<uint256_t> copy_vector(2);
407 for (size_t j = 0; j < 2; j++) {
408 copy_vector.emplace_back(engine.get_random_uint256());
409 copy_vector.emplace_back(engine.get_random_uint256());
410 copy_vector[0] += (1 - copy_vector[0].get_bit(0));
411 copy_vector[1] += (1 - copy_vector[1].get_bit(0));
412 }
413
414 for (auto _ : state) {
415 state.PauseTiming();
416 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
417 state.ResumeTiming();
418 for (size_t i = 0; i < num_cycles; i++) {
419 auto [r0, r1] = copy_vector[i & 1].mul_extended(copy_vector[1 - (i & 1)]);
420 state.PauseTiming();
421 copy_vector[i & 1] += r0;
422 copy_vector[1 - (i & 1)] += r1;
423 copy_vector[0] += (1 - copy_vector[0].get_bit(0));
424 copy_vector[1] += (1 - copy_vector[1].get_bit(0));
425 state.ResumeTiming();
426 }
427 }
428}
429
430/*
431 * @brief Load srs for pippenger
432 *
433 */
434static void DoPippengerSetup(const benchmark::State&)
435{
437}
438
451void pippenger(State& state)
452{
454 for (auto _ : state) {
455 state.PauseTiming();
456 size_t num_cycles = 1 << static_cast<size_t>(state.range(0));
457 Polynomial<Fr> pol(num_cycles);
458 for (size_t i = 0; i < num_cycles; i++) {
459 *(uint256_t*)&pol.at(i) = engine.get_random_uint256();
460 pol.at(i).self_reduce_once();
461 pol.at(i).self_reduce_once();
462 pol.at(i).self_reduce_once();
463 }
464
466 state.ResumeTiming();
467 benchmark::DoNotOptimize(ck.commit(pol));
468 }
469}
470
471void bn254fr_random(State& state)
472{
474 for (auto _ : state) {
475 state.PauseTiming();
476 size_t num_cycles = 1UL << static_cast<size_t>(state.range(0));
477 state.ResumeTiming();
478 for (size_t i = 0; i < num_cycles; i++) {
479 benchmark::DoNotOptimize(fr::random_element(&engine));
480 }
481 }
482}
483} // namespace
484
485BENCHMARK(parallel_for_field_element_addition)->Unit(kMicrosecond)->DenseRange(0, MAX_REPETITION_LOG);
486BENCHMARK(ff_addition)->Unit(kMicrosecond)->DenseRange(12, 30);
487BENCHMARK(ff_multiplication)->Unit(kMicrosecond)->DenseRange(12, 27);
488BENCHMARK(ff_sqr)->Unit(kMicrosecond)->DenseRange(12, 27);
489BENCHMARK(ff_invert)->Unit(kMicrosecond)->DenseRange(12, 19);
490BENCHMARK(ff_to_montgomery)->Unit(kMicrosecond)->DenseRange(12, 27);
491BENCHMARK(ff_from_montgomery)->Unit(kMicrosecond)->DenseRange(12, 27);
492BENCHMARK(ff_reduce)->Unit(kMicrosecond)->DenseRange(12, 29);
493BENCHMARK(projective_point_addition)->Unit(kMicrosecond)->DenseRange(12, 22);
494BENCHMARK(projective_point_accidental_doubling)->Unit(kMicrosecond)->DenseRange(12, 22);
495BENCHMARK(projective_point_doubling)->Unit(kMicrosecond)->DenseRange(12, 22);
496BENCHMARK(scalar_multiplication_bench)->Unit(kMicrosecond)->DenseRange(12, 18);
497BENCHMARK(cycle_waste)->Unit(kMicrosecond)->DenseRange(20, 30);
498BENCHMARK(sequential_copy)->Unit(kMicrosecond)->DenseRange(20, 25);
499BENCHMARK(uint_multiplication)->Unit(kMicrosecond)->DenseRange(12, 27);
500BENCHMARK(uint_extended_multiplication)->Unit(kMicrosecond)->DenseRange(12, 27);
501BENCHMARK(pippenger)->Unit(kMicrosecond)->DenseRange(16, 20)->Setup(DoPippengerSetup)->Iterations(5);
502BENCHMARK(bn254fr_random)->Unit(kMicrosecond)->DenseRange(10, 20);
BENCHMARK_MAIN()
#define MAX_REPETITION_LOG
BENCHMARK(parallel_for_field_element_addition) -> Unit(kMicrosecond) ->DenseRange(0, MAX_REPETITION_LOG)
CommitmentKey object over a pairing group 𝔾₁.
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
typename Group::element Element
Definition bn254.hpp:21
virtual uint256_t get_random_uint256()=0
numeric::RNG & engine
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:190
RNG & get_randomness()
Definition engine.cpp:203
Curve::Element pippenger(PolynomialSpan< const typename Curve::ScalarField > scalars, std::span< const typename Curve::AffineElement > points, bool handle_edge_cases) noexcept
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
std::conditional_t< IsGoblinBigGroup< C, Fq, Fr, G >, element_goblin::goblin_element< C, goblin_field< C >, Fr, G >, element_default::element< C, Fq, Fr, G > > element
element wraps either element_default::element or element_goblin::goblin_element depending on parametr...
Entry point for Barretenberg command-line interface.
size_t get_num_cpus()
Definition thread.hpp:12
CommitmentKey< Curve > ck
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
Definition thread.cpp:72
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static constexpr field one()
static field random_element(numeric::RNG *engine=nullptr) noexcept