Skip to content

Commit

Permalink
chore: add pow poly bench and link optimization issues (#4725)
Browse files Browse the repository at this point in the history
Adds the pow poly bench. This PR was supposed to also optimize the pow
poly computation, but I measured that it takes around 45ms of the whole
6-iter client IVC benchmark, so its not worth doing for now.

Links a couple of optimization issues to the codebase:
AztecProtocol/barretenberg#857 and
AztecProtocol/barretenberg#864.
  • Loading branch information
lucasxia01 authored Feb 23, 2024
1 parent 50f89f1 commit faa9586
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ template <typename Curve> class IPA {
// Compute G_zero
// First construct s_vec
std::vector<Fr> s_vec(poly_degree);
// TODO(https://github.com/AztecProtocol/barretenberg/issues/857): This code is not efficient as its O(nlogn).
// This can be optimized to be linear by computing a tree of products. Its very readable, so we're
// leaving it unoptimized for now.
run_loop_in_parallel_if_effective(
poly_degree,
[&s_vec, &round_challenges_inv, log_poly_degree](size_t start, size_t end) {
Expand Down
27 changes: 27 additions & 0 deletions barretenberg/cpp/src/barretenberg/polynomials/pow.bench.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "barretenberg/polynomials/pow.hpp"
#include "barretenberg/ecc/curves/bn254/fr.hpp"
#include <benchmark/benchmark.h>

using namespace benchmark;
using namespace bb;

namespace {

void compute_pow_poly(benchmark::State& state)
{
// just set up huge vector
std::vector<bb::fr> betas{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 };

for (auto _ : state) {
int64_t num_betas = state.range(0);
std::vector<bb::fr> cur_betas(betas.begin(), betas.begin() + num_betas);
PowPolynomial pow{ cur_betas };
pow.compute_values();
}
}

BENCHMARK(compute_pow_poly)->Unit(benchmark::kMillisecond)->Arg(20);

} // namespace
BENCHMARK_MAIN();
10 changes: 9 additions & 1 deletion barretenberg/cpp/src/barretenberg/polynomials/pow.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#pragma once
#include "barretenberg/common/compiler_hints.hpp"
#include "barretenberg/common/op_count.hpp"
#include "barretenberg/common/thread.hpp"

#include <cstddef>
Expand Down Expand Up @@ -121,8 +123,9 @@ template <typename FF> struct PowPolynomial {
* @brief Given \vec{β} = {β_0,...,β_{d-1}} compute pow_\vec{β}(i) for i=0,...,2^{d}-1
*
*/
void compute_values()
BB_PROFILE void compute_values()
{
BB_OP_COUNT_TIME();
size_t pow_size = 1 << betas.size();
pow_betas = std::vector<FF>(pow_size);

Expand All @@ -136,6 +139,11 @@ template <typename FF> struct PowPolynomial {
size_t num_threads = std::min(desired_num_threads, max_num_threads); // fewer than max if justified
num_threads = num_threads > 0 ? num_threads : 1; // ensure num threads is >= 1
size_t iterations_per_thread = pow_size / num_threads; // actual iterations per thread

// TODO(https://github.com/AztecProtocol/barretenberg/issues/864): This computation is asymtotically slow as it
// does pow_size * log(pow_size) work. However, in practice, its super efficient because its trivially
// parallelizable and only takes 45ms for the whole 6 iter IVC benchmark. Its also very readable, so we're
// leaving it unoptimized for now.
parallel_for(num_threads, [&](size_t thread_idx) {
size_t start = thread_idx * iterations_per_thread;
size_t end = (thread_idx + 1) * iterations_per_thread;
Expand Down

0 comments on commit faa9586

Please sign in to comment.