#[path = "common.rs"]
mod common;
use common::*;
use acpu::field::tip5::{tip5_hash_pair, tip5_hash_varlen, tip5_permute, tip5_permute_batch};
use twenty_first::prelude::{BFieldElement, Digest, Tip5};
fn rand_state(seed: u64) -> [u64; 16] {
let mut s = [0u64; 16];
let mut x = seed.wrapping_mul(0x9E37_79B9_7F4A_7C15) | 1;
for v in s.iter_mut() {
x = x.wrapping_mul(0x6C62_272E_07BB_0142).wrapping_add(1);
*v = BFieldElement::new(x).raw_u64();
}
s
}
fn main() {
let _ = acpu::sync::affinity::pin_p_core();
let caps = acpu::probe::scan();
println!("acpu Tip5 microbench β {:?}", caps.chip);
println!();
let mut score = Score::vs("twenty-first");
score.hdr("TIP5 (vs twenty_first 1.1)");
let seed = 0xA1B2_C3D4_E5F6_0708u64;
let initial = rand_state(seed);
let acpu_perm_ns = best_of(
|| {
let mut s = initial;
for _ in 0..256 {
tip5_permute(&mut s);
}
std::hint::black_box(&s);
},
400,
);
let acpu_per = acpu_perm_ns as f64 / 256.0;
let tw_perm_ns = best_of(
|| {
let mut t = Tip5 {
state: initial
.map(BFieldElement::from_raw_u64),
};
for _ in 0..256 {
t.permutation();
}
std::hint::black_box(&t);
},
400,
);
let tw_per = tw_perm_ns as f64 / 256.0;
score.row("permute (1Γ)", acpu_per as u64, tw_per as u64);
let acpu_batch4_ns = best_of(
|| {
let mut s = [initial; 4];
for _ in 0..256 {
tip5_permute_batch::<4>(&mut s);
}
std::hint::black_box(&s);
},
400,
);
let acpu_batch4_per = acpu_batch4_ns as f64 / (256.0 * 4.0);
score.row("permute batchΓ4 (per perm)", acpu_batch4_per as u64, tw_per as u64);
let acpu_batch8_ns = best_of(
|| {
let mut s = [initial; 8];
for _ in 0..128 {
tip5_permute_batch::<8>(&mut s);
}
std::hint::black_box(&s);
},
400,
);
let acpu_batch8_per = acpu_batch8_ns as f64 / (128.0 * 8.0);
score.row("permute batchΓ8 (per perm)", acpu_batch8_per as u64, tw_per as u64);
let left = [initial[0], initial[1], initial[2], initial[3], initial[4]];
let right = [initial[5], initial[6], initial[7], initial[8], initial[9]];
let acpu_pair_ns = best_of(
|| {
for _ in 0..256 {
let d = tip5_hash_pair(left, right);
std::hint::black_box(d);
}
},
400,
);
let acpu_pair_per = acpu_pair_ns as f64 / 256.0;
let l_d = Digest::new(left.map(BFieldElement::from_raw_u64));
let r_d = Digest::new(right.map(BFieldElement::from_raw_u64));
let tw_pair_ns = best_of(
|| {
for _ in 0..256 {
let d = Tip5::hash_pair(l_d, r_d);
std::hint::black_box(d);
}
},
400,
);
let tw_pair_per = tw_pair_ns as f64 / 256.0;
score.row("hash_pair", acpu_pair_per as u64, tw_pair_per as u64);
let bfe_in: Vec<BFieldElement> = (0..100u64).map(BFieldElement::new).collect();
let raw_in: Vec<u64> = bfe_in.iter().map(|e| e.raw_u64()).collect();
let acpu_var_ns = best_of(
|| {
for _ in 0..32 {
let d = tip5_hash_varlen(&raw_in);
std::hint::black_box(d);
}
},
400,
);
let acpu_var_per = acpu_var_ns as f64 / 32.0;
let tw_var_ns = best_of(
|| {
for _ in 0..32 {
let d = Tip5::hash_varlen(&bfe_in);
std::hint::black_box(d);
}
},
400,
);
let tw_var_per = tw_var_ns as f64 / 32.0;
score.row("hash_varlen[100]", acpu_var_per as u64, tw_var_per as u64);
println!();
println!("derived rates");
println!(
" acpu permute single : {:>7.1} ns ({:.2} Mperm/s)",
acpu_per,
1.0e3 / acpu_per
);
println!(
" twenty-first single : {:>7.1} ns ({:.2} Mperm/s)",
tw_per,
1.0e3 / tw_per
);
println!(
" acpu permute batchΓ8 : {:>7.1} ns/perm ({:.2} Mperm/s)",
acpu_batch8_per,
1.0e3 / acpu_batch8_per
);
score.summary();
}