Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
indexed_tree.bench.cpp
Go to the documentation of this file.
10#include <benchmark/benchmark.h>
11#include <filesystem>
12#include <memory>
13#include <vector>
14
15using namespace benchmark;
16using namespace bb::crypto::merkle_tree;
17
19
22
23const size_t TREE_DEPTH = 40;
24const size_t MAX_BATCH_SIZE = 64;
25
26template <typename TreeType> void add_values(TreeType& tree, const std::vector<NullifierLeafValue>& values)
27{
28 Signal signal(1);
29 bool success = true;
30 std::string error_message;
31 typename TreeType::AddCompletionCallback completion = [&](const auto& result) -> void {
32 success = result.success;
33 error_message = result.message;
34 signal.signal_level(0);
35 };
36
37 tree.add_or_update_values(values, completion);
38 signal.wait_for_level(0);
39 if (!success) {
40 throw std::runtime_error(format("Failed to add values: ", error_message));
41 }
42}
43
44template <typename TreeType> void add_values_with_witness(TreeType& tree, const std::vector<NullifierLeafValue>& values)
45{
46 bool success = true;
47 std::string error_message;
48 Signal signal(1);
49 typename TreeType::AddCompletionCallbackWithWitness completion = [&](const auto& result) -> void {
50 success = result.success;
51 error_message = result.message;
52 signal.signal_level(0);
53 };
54
55 tree.add_or_update_values(values, completion);
56 signal.wait_for_level(0);
57 if (!success) {
58 throw std::runtime_error(format("Failed to add values with witness: ", error_message));
59 }
60}
61
62template <typename TreeType> void add_values_sequentially(TreeType& tree, const std::vector<NullifierLeafValue>& values)
63{
64 bool success = true;
65 std::string error_message;
66 Signal signal(1);
67 typename TreeType::AddCompletionCallback completion = [&](const auto& result) -> void {
68 success = result.success;
69 error_message = result.message;
70 signal.signal_level(0);
71 };
72
73 tree.add_or_update_values_sequentially(values, completion);
74 signal.wait_for_level(0);
75 if (!success) {
76 throw std::runtime_error(format("Failed to add values sequentially: ", error_message));
77 }
78}
79
80template <typename TreeType>
82{
83 bool success = true;
84 std::string error_message;
85 Signal signal(1);
86 typename TreeType::AddSequentiallyCompletionCallbackWithWitness completion = [&](const auto& result) -> void {
87 success = result.success;
88 error_message = result.message;
89 signal.signal_level(0);
90 };
91
92 tree.add_or_update_values_sequentially(values, completion);
93 signal.wait_for_level(0);
94 if (!success) {
95 throw std::runtime_error(format("Failed to add values sequentially with witness: ", error_message));
96 }
97}
98
100
101template <typename TreeType, InsertionStrategy strategy> void multi_thread_indexed_tree_bench(State& state) noexcept
102{
103 const size_t batch_size = size_t(state.range(0));
104 const size_t depth = TREE_DEPTH;
105
106 std::string directory = random_temp_directory();
107 std::string name = random_string();
108 std::filesystem::create_directories(directory);
109 uint32_t num_threads = 16;
110
111 LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
114 TreeType tree = TreeType(std::move(store), workers, batch_size);
115
116 const size_t initial_size = 1024 * 16;
117 std::vector<NullifierLeafValue> initial_batch(initial_size);
118 for (size_t i = 0; i < initial_size; ++i) {
119 initial_batch[i] = fr(random_engine.get_random_uint256());
120 }
121 if (strategy == SEQUENTIAL) {
122 add_values_sequentially(tree, initial_batch);
123 } else {
124 add_values(tree, initial_batch);
125 }
126
127 for (auto _ : state) {
128 state.PauseTiming();
129 std::vector<NullifierLeafValue> values(batch_size);
130 for (size_t i = 0; i < batch_size; ++i) {
131 values[i] = fr(random_engine.get_random_uint256());
132 }
133 state.ResumeTiming();
134 if (strategy == SEQUENTIAL) {
135 add_values_sequentially(tree, values);
136 } else {
137 add_values(tree, values);
138 }
139 }
140}
141
142template <typename TreeType, InsertionStrategy strategy> void single_thread_indexed_tree_bench(State& state) noexcept
143{
144 const size_t batch_size = size_t(state.range(0));
145 const size_t depth = TREE_DEPTH;
146
147 std::string directory = random_temp_directory();
148 std::string name = random_string();
149 std::filesystem::create_directories(directory);
150 uint32_t num_threads = 1;
151
152 LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
155 TreeType tree = TreeType(std::move(store), workers, batch_size);
156
157 const size_t initial_size = 1024 * 16;
158 std::vector<NullifierLeafValue> initial_batch(initial_size);
159 for (size_t i = 0; i < initial_size; ++i) {
160 initial_batch[i] = fr(random_engine.get_random_uint256());
161 }
162 if (strategy == SEQUENTIAL) {
163 add_values_sequentially(tree, initial_batch);
164 } else {
165 add_values(tree, initial_batch);
166 }
167
168 for (auto _ : state) {
169 state.PauseTiming();
170 std::vector<NullifierLeafValue> values(batch_size);
171 for (size_t i = 0; i < batch_size; ++i) {
172 values[i] = fr(random_engine.get_random_uint256());
173 }
174 state.ResumeTiming();
175 if (strategy == SEQUENTIAL) {
176 add_values_sequentially(tree, values);
177 } else {
178 add_values(tree, values);
179 }
180 }
181}
182
183template <typename TreeType, InsertionStrategy strategy>
185{
186 const size_t batch_size = size_t(state.range(0));
187 const size_t depth = TREE_DEPTH;
188
189 std::string directory = random_temp_directory();
190 std::string name = random_string();
191 std::filesystem::create_directories(directory);
192 uint32_t num_threads = 16;
193
194 LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
197 TreeType tree = TreeType(std::move(store), workers, batch_size);
198
199 const size_t initial_size = 1024 * 16;
200 std::vector<NullifierLeafValue> initial_batch(initial_size);
201 for (size_t i = 0; i < initial_size; ++i) {
202 initial_batch[i] = fr(random_engine.get_random_uint256());
203 }
204 if (strategy == SEQUENTIAL) {
205 add_values_sequentially(tree, initial_batch);
206 } else {
207 add_values(tree, initial_batch);
208 }
209
210 for (auto _ : state) {
211 state.PauseTiming();
212 std::vector<NullifierLeafValue> values(batch_size);
213 for (size_t i = 0; i < batch_size; ++i) {
214 values[i] = fr(random_engine.get_random_uint256());
215 }
216 state.ResumeTiming();
217 if (strategy == SEQUENTIAL) {
219 } else {
220 add_values_with_witness(tree, values);
221 }
222 }
223}
224
225template <typename TreeType, InsertionStrategy strategy>
227{
228 const size_t batch_size = size_t(state.range(0));
229 const size_t depth = TREE_DEPTH;
230
231 std::string directory = random_temp_directory();
232 std::string name = random_string();
233 std::filesystem::create_directories(directory);
234 uint32_t num_threads = 1;
235
236 LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
239 TreeType tree = TreeType(std::move(store), workers, batch_size);
240
241 const size_t initial_size = 1024 * 16;
242 std::vector<NullifierLeafValue> initial_batch(initial_size);
243 for (size_t i = 0; i < initial_size; ++i) {
244 initial_batch[i] = fr(random_engine.get_random_uint256());
245 }
246 if (strategy == SEQUENTIAL) {
247 add_values_sequentially(tree, initial_batch);
248 } else {
249 add_values(tree, initial_batch);
250 }
251
252 for (auto _ : state) {
253 state.PauseTiming();
254 std::vector<NullifierLeafValue> values(batch_size);
255 for (size_t i = 0; i < batch_size; ++i) {
256 values[i] = fr(random_engine.get_random_uint256());
257 }
258 state.ResumeTiming();
259 if (strategy == SEQUENTIAL) {
261 } else {
262 add_values_with_witness(tree, values);
263 }
264 }
265}
266
267BENCHMARK(single_thread_indexed_tree_with_witness_bench<Poseidon2, BATCH>)
268 ->Unit(benchmark::kMillisecond)
269 ->RangeMultiplier(2)
270 ->Range(2, MAX_BATCH_SIZE)
271 ->Iterations(1000);
272
273BENCHMARK(single_thread_indexed_tree_with_witness_bench<Poseidon2, BATCH>)
274 ->Unit(benchmark::kMillisecond)
275 ->RangeMultiplier(2)
276 ->Range(512, 8192)
277 ->Iterations(10);
278
279BENCHMARK(single_thread_indexed_tree_with_witness_bench<Poseidon2, SEQUENTIAL>)
280 ->Unit(benchmark::kMillisecond)
281 ->RangeMultiplier(2)
282 ->Range(2, MAX_BATCH_SIZE)
283 ->Iterations(1000);
284
285BENCHMARK(single_thread_indexed_tree_with_witness_bench<Poseidon2, SEQUENTIAL>)
286 ->Unit(benchmark::kMillisecond)
287 ->RangeMultiplier(2)
288 ->Range(512, 8192)
289 ->Iterations(10);
290
291BENCHMARK(multi_thread_indexed_tree_with_witness_bench<Poseidon2, BATCH>)
292 ->Unit(benchmark::kMillisecond)
293 ->RangeMultiplier(2)
294 ->Range(2, MAX_BATCH_SIZE)
295 ->Iterations(1000);
296
297BENCHMARK(multi_thread_indexed_tree_with_witness_bench<Poseidon2, BATCH>)
298 ->Unit(benchmark::kMillisecond)
299 ->RangeMultiplier(2)
300 ->Range(512, 8192)
301 ->Iterations(10);
302
303BENCHMARK(multi_thread_indexed_tree_with_witness_bench<Poseidon2, SEQUENTIAL>)
304 ->Unit(benchmark::kMillisecond)
305 ->RangeMultiplier(2)
306 ->Range(2, MAX_BATCH_SIZE)
307 ->Iterations(1000);
308
309BENCHMARK(multi_thread_indexed_tree_with_witness_bench<Poseidon2, SEQUENTIAL>)
310 ->Unit(benchmark::kMillisecond)
311 ->RangeMultiplier(2)
312 ->Range(512, 8192)
313 ->Iterations(10);
314
315BENCHMARK(single_thread_indexed_tree_bench<Poseidon2, BATCH>)
316 ->Unit(benchmark::kMillisecond)
317 ->RangeMultiplier(2)
318 ->Range(2, MAX_BATCH_SIZE)
319 ->Iterations(1000);
320
321BENCHMARK(single_thread_indexed_tree_bench<Poseidon2, BATCH>)
322 ->Unit(benchmark::kMillisecond)
323 ->RangeMultiplier(2)
324 ->Range(512, 8192)
325 ->Iterations(10);
326
327BENCHMARK(single_thread_indexed_tree_bench<Poseidon2, SEQUENTIAL>)
328 ->Unit(benchmark::kMillisecond)
329 ->RangeMultiplier(2)
330 ->Range(2, MAX_BATCH_SIZE)
331 ->Iterations(1000);
332
333BENCHMARK(single_thread_indexed_tree_bench<Poseidon2, SEQUENTIAL>)
334 ->Unit(benchmark::kMillisecond)
335 ->RangeMultiplier(2)
336 ->Range(512, 8192)
337 ->Iterations(10);
338
339BENCHMARK(multi_thread_indexed_tree_bench<Poseidon2, BATCH>)
340 ->Unit(benchmark::kMillisecond)
341 ->RangeMultiplier(2)
342 ->Range(2, MAX_BATCH_SIZE)
343 ->Iterations(1000);
344
345BENCHMARK(multi_thread_indexed_tree_bench<Poseidon2, BATCH>)
346 ->Unit(benchmark::kMillisecond)
347 ->RangeMultiplier(2)
348 ->Range(512, 8192)
349 ->Iterations(100);
350
351BENCHMARK(multi_thread_indexed_tree_bench<Poseidon2, SEQUENTIAL>)
352 ->Unit(benchmark::kMillisecond)
353 ->RangeMultiplier(2)
354 ->Range(2, MAX_BATCH_SIZE)
355 ->Iterations(1000);
356
357BENCHMARK(multi_thread_indexed_tree_bench<Poseidon2, SEQUENTIAL>)
358 ->Unit(benchmark::kMillisecond)
359 ->RangeMultiplier(2)
360 ->Range(512, 8192)
361 ->Iterations(100);
362
Serves as a key-value node store for merkle trees. Caches all changes in memory before persisting the...
Implements a parallelized batch insertion indexed tree Accepts template argument of the type of store...
std::shared_ptr< LMDBTreeStore > SharedPtr
Used in parallel insertions in the the IndexedTree. Workers signal to other following workes as they ...
Definition signal.hpp:17
void signal_level(uint32_t level=0)
Signals that the given level has been passed.
Definition signal.hpp:54
void wait_for_level(uint32_t level=0)
Causes the thread to wait until the required level has been signalled.
Definition signal.hpp:40
std::string format(Args... args)
Definition log.hpp:20
void single_thread_indexed_tree_with_witness_bench(State &state) noexcept
void add_values_sequentially(TreeType &tree, const std::vector< NullifierLeafValue > &values)
void add_values_with_witness(TreeType &tree, const std::vector< NullifierLeafValue > &values)
const size_t TREE_DEPTH
BENCHMARK_MAIN()
const size_t MAX_BATCH_SIZE
void multi_thread_indexed_tree_bench(State &state) noexcept
void single_thread_indexed_tree_bench(State &state) noexcept
void add_values_sequentially_with_witness(TreeType &tree, const std::vector< NullifierLeafValue > &values)
InsertionStrategy
void multi_thread_indexed_tree_with_witness_bench(State &state) noexcept
void add_values(TreeType &tree, const std::vector< NullifierLeafValue > &values)
MerkleTree< MemoryStore, PedersenHashPolicy > TreeType
std::string random_temp_directory()
Definition fixtures.hpp:42
std::string random_string()
Definition fixtures.hpp:35
field< Bn254FrParams > fr
Definition fr.hpp:174
BENCHMARK(vector_of_evaluations) -> DenseRange(15, 21) ->Unit(kMillisecond) ->Iterations(1)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13