smt: add benchmarks for parallel construction
This commit is contained in:
parent
cc144a6ef5
commit
ec2dfdf4b8
3 changed files with 107 additions and 1 deletions
|
@ -35,6 +35,11 @@ harness = false
|
||||||
name = "merkle"
|
name = "merkle"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "parallel-subtree"
|
||||||
|
harness = false
|
||||||
|
required-features = ["concurrent"]
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "store"
|
name = "store"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
75
benches/parallel-subtree.rs
Normal file
75
benches/parallel-subtree.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
use std::{fmt::Debug, hint, mem, time::Duration};
|
||||||
|
|
||||||
|
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
|
||||||
|
use miden_crypto::{hash::rpo::RpoDigest, merkle::Smt, Felt, Word, ONE};
|
||||||
|
use rand_utils::prng_array;
|
||||||
|
use winter_utils::Randomizable;
|
||||||
|
|
||||||
|
// 2^0, 2^4, 2^8, 2^12, 2^16
|
||||||
|
const PAIR_COUNTS: [u64; 6] = [1, 16, 256, 4096, 65536, 1_048_576];
|
||||||
|
|
||||||
|
fn smt_parallel_subtree(c: &mut Criterion) {
|
||||||
|
let mut seed = [0u8; 32];
|
||||||
|
|
||||||
|
let mut group = c.benchmark_group("parallel-subtrees");
|
||||||
|
|
||||||
|
for pair_count in PAIR_COUNTS {
|
||||||
|
let bench_id = BenchmarkId::from_parameter(pair_count);
|
||||||
|
group.bench_with_input(bench_id, &pair_count, |b, &pair_count| {
|
||||||
|
b.iter_batched(
|
||||||
|
|| {
|
||||||
|
// Setup.
|
||||||
|
let entries: Vec<(RpoDigest, Word)> = (0..pair_count)
|
||||||
|
.map(|i| {
|
||||||
|
let count = pair_count as f64;
|
||||||
|
let idx = ((i as f64 / count) * (count)) as u64;
|
||||||
|
let key = RpoDigest::new([
|
||||||
|
generate_value(&mut seed),
|
||||||
|
ONE,
|
||||||
|
Felt::new(i),
|
||||||
|
Felt::new(idx),
|
||||||
|
]);
|
||||||
|
let value = generate_word(&mut seed);
|
||||||
|
(key, value)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let control = Smt::with_entries(entries.clone()).unwrap();
|
||||||
|
(entries, control)
|
||||||
|
},
|
||||||
|
|(entries, control)| {
|
||||||
|
// Benchmarked function.
|
||||||
|
let tree = Smt::with_entries_par(hint::black_box(entries)).unwrap();
|
||||||
|
assert_eq!(tree.root(), control.root());
|
||||||
|
},
|
||||||
|
BatchSize::SmallInput,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group! {
|
||||||
|
name = smt_subtree_group;
|
||||||
|
config = Criterion::default()
|
||||||
|
//.measurement_time(Duration::from_secs(960))
|
||||||
|
.measurement_time(Duration::from_secs(60))
|
||||||
|
.sample_size(10)
|
||||||
|
.configure_from_args();
|
||||||
|
targets = smt_parallel_subtree
|
||||||
|
}
|
||||||
|
criterion_main!(smt_subtree_group);
|
||||||
|
|
||||||
|
// HELPER FUNCTIONS
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fn generate_value<T: Copy + Debug + Randomizable>(seed: &mut [u8; 32]) -> T {
|
||||||
|
mem::swap(seed, &mut prng_array(*seed));
|
||||||
|
let value: [T; 1] = rand_utils::prng_array(*seed);
|
||||||
|
value[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_word(seed: &mut [u8; 32]) -> Word {
|
||||||
|
mem::swap(seed, &mut prng_array(*seed));
|
||||||
|
let nums: [u64; 4] = prng_array(*seed);
|
||||||
|
[Felt::new(nums[0]), Felt::new(nums[1]), Felt::new(nums[2]), Felt::new(nums[3])]
|
||||||
|
}
|
28
src/main.rs
28
src/main.rs
|
@ -33,7 +33,12 @@ pub fn benchmark_smt() {
|
||||||
entries.push((key, value));
|
entries.push((key, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tree = construction(entries, tree_size).unwrap();
|
let mut tree = construction(entries.clone(), tree_size).unwrap();
|
||||||
|
#[cfg(feature = "concurrent")]
|
||||||
|
{
|
||||||
|
let parallel = parallel_construction(entries, tree_size).unwrap();
|
||||||
|
assert_eq!(tree, parallel);
|
||||||
|
}
|
||||||
insertion(&mut tree, tree_size).unwrap();
|
insertion(&mut tree, tree_size).unwrap();
|
||||||
batched_insertion(&mut tree, tree_size).unwrap();
|
batched_insertion(&mut tree, tree_size).unwrap();
|
||||||
proof_generation(&mut tree, tree_size).unwrap();
|
proof_generation(&mut tree, tree_size).unwrap();
|
||||||
|
@ -56,6 +61,27 @@ pub fn construction(entries: Vec<(RpoDigest, Word)>, size: u64) -> Result<Smt, M
|
||||||
Ok(tree)
|
Ok(tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "concurrent")]
|
||||||
|
pub fn parallel_construction(
|
||||||
|
entries: Vec<(RpoDigest, Word)>,
|
||||||
|
size: u64,
|
||||||
|
) -> Result<Smt, MerkleError> {
|
||||||
|
println!("Running a parallel construction benchmark:");
|
||||||
|
let now = Instant::now();
|
||||||
|
|
||||||
|
let tree = Smt::with_entries_par(entries).unwrap();
|
||||||
|
|
||||||
|
let elapsed = now.elapsed();
|
||||||
|
println!(
|
||||||
|
"Parallel-constructed an SMT with {} key-value pairs in {:.3} seconds",
|
||||||
|
size,
|
||||||
|
elapsed.as_secs_f32(),
|
||||||
|
);
|
||||||
|
println!("Number of leaf nodes: {}\n", tree.leaves().count());
|
||||||
|
|
||||||
|
Ok(tree)
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs the insertion benchmark for the [`Smt`].
|
/// Runs the insertion benchmark for the [`Smt`].
|
||||||
pub fn insertion(tree: &mut Smt, size: u64) -> Result<(), MerkleError> {
|
pub fn insertion(tree: &mut Smt, size: u64) -> Result<(), MerkleError> {
|
||||||
println!("Running an insertion benchmark:");
|
println!("Running an insertion benchmark:");
|
||||||
|
|
Loading…
Add table
Reference in a new issue