2#include "barretenberg/bbapi/generated/bb_ipc_client.hpp"
3#include "barretenberg/bbapi/generated/bb_types.hpp"
8#include <benchmark/benchmark.h>
18using namespace benchmark;
23void poseidon_hash_direct(State& state)
noexcept
27 for (
auto _ : state) {
28 std::vector<fr> to_hash{ x, y };
33BENCHMARK(poseidon_hash_direct)->Unit(benchmark::kMicrosecond)->Iterations(10000);
36static pid_t spawn_bb_msgpack_server(
const std::string& path)
38 pid_t bb_pid = fork();
41 int devnull = open(
"/dev/null", O_WRONLY);
43 dup2(devnull, STDOUT_FILENO);
44 dup2(devnull, STDERR_FILENO);
54 for (
const char* bb_path : bb_paths) {
55 execl(bb_path, bb_path,
"msgpack",
"run",
"--input", path.c_str(),
nullptr);
63enum class TransportType { Socket, Shm };
69template <TransportType Transport,
size_t NumClients>
class Poseidon2BBMsgpack :
public Fixture {
71 static_assert(NumClients >= 1,
"Must have at least 1 client");
75 std::array<std::thread, (NumClients > 1 ? NumClients - 1 : 1)> background_threads{};
76 std::atomic<bool> stop_background{
false };
84 if constexpr (Transport == TransportType::Socket) {
85 ipc_path =
"/tmp/poseidon_bb_msgpack_bench.sock";
88 ipc_path =
"/p2_bench.shm";
93 bool socket_exists(
const char* path,
int max_attempts = 20)
95 for (
int i = 0; i < max_attempts; i++) {
97 if (stat(path, &st) == 0 && S_ISSOCK(st.st_mode)) {
100 std::this_thread::sleep_for(std::chrono::milliseconds(50));
105 void SetUp(const ::benchmark::State& )
override
110 bb_pid = spawn_bb_msgpack_server(ipc_path);
112 throw std::runtime_error(
"Failed to fork bb process");
116 if constexpr (Transport == TransportType::Socket) {
118 if (!socket_exists(ipc_path.c_str())) {
119 kill(bb_pid, SIGKILL);
120 waitpid(bb_pid,
nullptr, 0);
121 throw std::runtime_error(
"BB binary failed to create socket within timeout");
123 std::this_thread::sleep_for(std::chrono::milliseconds(50));
126 std::this_thread::sleep_for(std::chrono::milliseconds(500));
129 for (
size_t i = 0; i < NumClients; i++) {
134 if constexpr (NumClients > 1) {
135 for (
size_t i = 1; i < NumClients; i++) {
136 background_threads[i - 1] = std::thread([
this, i]() {
141 auto response = clients[i]->poseidon2_hash(
143 DoNotOptimize(response.hash);
154 void TearDown(const ::benchmark::State& )
override
157 if constexpr (NumClients > 1) {
159 for (
size_t i = 0; i < NumClients - 1; i++) {
160 if (background_threads[i].joinable()) {
161 background_threads[i].join();
167 for (
auto& client : clients) {
173 kill(bb_pid, SIGTERM);
175 pid_t result = waitpid(bb_pid, &status, 0);
178 kill(bb_pid, SIGKILL);
179 waitpid(bb_pid,
nullptr, 0);
185 void run_benchmark(benchmark::State& state)
187 for (
auto _ : state) {
190 DoNotOptimize(response.hash);
197using Poseidon2BBSocketSPSC = Poseidon2BBMsgpack<TransportType::Socket, 1>;
198using Poseidon2BBShmSPSC = Poseidon2BBMsgpack<TransportType::Shm, 1>;
201using Poseidon2BBSocketMPSC = Poseidon2BBMsgpack<TransportType::Socket, 3>;
204#define REGISTER_BB_BENCHMARK(fixture_name) \
205 BENCHMARK_DEFINE_F(fixture_name, poseidon_hash_roundtrip)(benchmark::State & state) \
207 run_benchmark(state); \
209 BENCHMARK_REGISTER_F(fixture_name, poseidon_hash_roundtrip)->Unit(benchmark::kMicrosecond)->Iterations(10000)
Wire <-> domain conversion helpers for the bbapi handlers.
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
#define REGISTER_BB_BENCHMARK(fixture_name)
Fr fr_to_wire(const bb::fr &d)
Entry point for Barretenberg command-line interface.
BENCHMARK(bench_commit_structured_random_poly< curve::BN254 >) -> Unit(benchmark::kMillisecond)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept