use std::hint::black_box;
use criterion::{criterion_group, criterion_main, Criterion, Throughput};
use subetha_pointers::adaptive_cheri_pointer::{
CapabilityPermission, OwnedReadableCapability, OwnedWritableCapability,
ReadableCapability, WritableCapability,
};
use subetha_pointers::adaptive_rasp_batch::{RaspBatch, RaspPermission};
fn group_capability_validation(c: &mut Criterion) {
let mut grp = c.benchmark_group("capability_validation_10k");
grp.throughput(Throughput::Elements(10_000));
let storages: Vec<Vec<u64>> = (0..10_000).map(|i| vec![i as u64]).collect();
let mut soa: RaspBatch<u64> = RaspBatch::with_capacity(10_000);
for s in &storages {
soa.push_from_slice(s, RaspPermission::Read as u32).unwrap();
}
grp.bench_function("rasp_soa_count_valid_scalar", |b| {
b.iter(|| {
let ok = soa.count_valid_scalar();
black_box(ok)
});
});
if std::is_x86_feature_detected!("avx2") {
#[target_feature(enable = "avx2")]
unsafe fn run_soa_count_avx2(soa: &RaspBatch<u64>) -> u32 {
unsafe { soa.count_valid_avx2() }
}
grp.bench_function("rasp_soa_count_valid_avx2", |b| {
b.iter(|| {
let ok = unsafe { run_soa_count_avx2(&soa) };
black_box(ok)
});
});
}
if std::is_x86_feature_detected!("avx512f") {
#[target_feature(enable = "avx512f")]
unsafe fn run_soa_count_avx512(soa: &RaspBatch<u64>) -> u32 {
unsafe { soa.count_valid_avx512() }
}
grp.bench_function("rasp_soa_count_valid_avx512", |b| {
b.iter(|| {
let ok = unsafe { run_soa_count_avx512(&soa) };
black_box(ok)
});
});
}
drop(soa);
let read_caps: Vec<ReadableCapability<u64>> = storages.iter().map(|s| {
let (c, _a) = ReadableCapability::from_slice(
s.as_slice(), CapabilityPermission::Read as u32,
);
c
}).collect();
grp.bench_function("readable_capability_read", |b| {
b.iter(|| {
let mut sum = 0u64;
for c in &read_caps {
if let Ok(v) = c.read() { sum = sum.wrapping_add(v); }
}
black_box(sum)
});
});
drop(read_caps);
grp.bench_function("baseline_native_slice_check", |b| {
b.iter(|| {
let mut sum = 0u64;
for s in &storages {
if !s.is_empty() { sum = sum.wrapping_add(s[0]); }
}
black_box(sum)
});
});
let mut storages = storages;
grp.bench_function("writable_capability_write_then_read", |b| {
b.iter(|| {
let mut sum = 0u64;
for s in storages.iter_mut() {
let (mut c, _a) = WritableCapability::from_slice_mut(s.as_mut_slice());
c.write(42).expect("capability write");
if let Ok(v) = c.read() { sum = sum.wrapping_add(v); }
}
black_box(sum)
});
});
grp.bench_function("baseline_native_slice_write_then_read", |b| {
b.iter(|| {
let mut sum = 0u64;
for s in storages.iter_mut() {
if !s.is_empty() {
s[0] = 42;
sum = sum.wrapping_add(s[0]);
}
}
black_box(sum)
});
});
grp.finish();
}
fn group_owned_capability_raii(c: &mut Criterion) {
let mut grp = c.benchmark_group("owned_capability_construct_drop_1k");
grp.throughput(Throughput::Elements(1_000));
grp.bench_function("owned_readable_construct_then_drop", |b| {
b.iter(|| {
for i in 0..1_000u64 {
let owned = OwnedReadableCapability::new(i);
black_box(owned.read().expect("capability read"));
}
});
});
grp.bench_function("owned_writable_construct_write_drop", |b| {
b.iter(|| {
for i in 0..1_000u64 {
let mut owned = OwnedWritableCapability::new(i);
owned.cap_mut().write(i.wrapping_add(1)).expect("capability write");
black_box(owned.read().expect("capability read"));
}
});
});
grp.bench_function("baseline_box_new_drop", |b| {
b.iter(|| {
for i in 0..1_000u64 {
let b = Box::new(i);
black_box(*b);
}
});
});
grp.finish();
}
criterion_group!(benches, group_capability_validation, group_owned_capability_raii);
criterion_main!(benches);