Skip to content

Commit 98b7048

Browse files
[runtime/utils/buffer/paged/append] zero-copy writes (#3434)
Co-authored-by: Patrick O'Grady <me@patrickogrady.xyz>
1 parent b95583c commit 98b7048

4 files changed

Lines changed: 257 additions & 100 deletions

File tree

runtime/src/utils/buffer/benches/append.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
//! Benchmark sequential append performance.
22
33
use super::{create_append, destroy_append, CACHE_SIZE, PAGE_SIZE};
4-
use commonware_runtime::{buffer::paged::CacheRef, deterministic, Runner as _};
4+
use commonware_runtime::{
5+
buffer::paged::CacheRef, deterministic, tokio, BufferPooler, Runner, Storage,
6+
};
57
use commonware_utils::NZUsize;
68
use criterion::Criterion;
79
use std::time::Instant;
810

9-
pub fn bench(c: &mut Criterion) {
10-
for chunk_size in [64, 256, 1024, 4096] {
11-
c.bench_function(&format!("{}/chunk={}", module_path!(), chunk_size), |b| {
11+
fn bench_backend<R>(c: &mut Criterion, backend: &str, chunk_size: usize)
12+
where
13+
R: Runner + Default,
14+
R::Context: Storage + BufferPooler,
15+
{
16+
c.bench_function(
17+
&format!("{}/backend={backend} chunk={chunk_size}", module_path!()),
18+
|b| {
1219
b.iter_custom(|iters| {
13-
let name = format!("append_seq_{chunk_size}").into_bytes();
20+
let name = format!("append_seq_{backend}_{chunk_size}").into_bytes();
1421
let data = vec![0xABu8; chunk_size];
1522

16-
let executor = deterministic::Runner::default();
23+
let executor = R::default();
1724
executor.start(|ctx| async move {
1825
let cache_ref = CacheRef::from_pooler(&ctx, PAGE_SIZE, NZUsize!(CACHE_SIZE));
1926
let append = create_append(&ctx, &name, cache_ref).await;
@@ -32,6 +39,13 @@ pub fn bench(c: &mut Criterion) {
3239
elapsed
3340
})
3441
});
35-
});
42+
},
43+
);
44+
}
45+
46+
pub fn bench(c: &mut Criterion) {
47+
for chunk_size in [64, 256, 1024, 4096] {
48+
bench_backend::<deterministic::Runner>(c, "deterministic", chunk_size);
49+
bench_backend::<tokio::Runner>(c, "tokio", chunk_size);
3650
}
3751
}

runtime/src/utils/buffer/benches/bench.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
//! Benchmarks for the page cache via the Append blob wrapper.
22
//!
3-
//! Uses memory-based storage (deterministic runtime) to isolate
4-
//! page cache performance from disk I/O.
3+
//! Includes both deterministic in-memory runs to isolate buffer/page-cache work
4+
//! and Tokio-backed runs to exercise real storage I/O paths.
55
//!
66
//! Run with: `cargo bench --bench buffer_paged -p commonware-runtime`
77
88
use commonware_runtime::{
99
buffer::paged::{Append, CacheRef},
10-
deterministic::Context,
11-
Storage as _,
10+
Storage,
1211
};
1312
use commonware_utils::NZU16;
1413
use criterion::{criterion_group, criterion_main};
@@ -22,17 +21,15 @@ const PAGE_SIZE_USIZE: usize = PAGE_SIZE.get() as usize;
2221
const WRITE_BUFFER_SIZE: usize = PAGE_SIZE_USIZE * 4;
2322
const CACHE_SIZE: usize = 10_000;
2423

25-
type MemBlob = <Context as commonware_runtime::Storage>::Blob;
26-
2724
/// Create a new Append wrapper for benchmarking.
28-
async fn create_append(ctx: &Context, name: &[u8], cache_ref: CacheRef) -> Append<MemBlob> {
25+
async fn create_append<C: Storage>(ctx: &C, name: &[u8], cache_ref: CacheRef) -> Append<C::Blob> {
2926
let (blob, size) = ctx.open("bench_partition", name).await.unwrap();
3027
Append::new(blob, size, WRITE_BUFFER_SIZE, cache_ref)
3128
.await
3229
.unwrap()
3330
}
3431

35-
async fn destroy_append(ctx: &Context, append: Append<MemBlob>, name: &[u8]) {
32+
async fn destroy_append<C: Storage>(ctx: &C, append: Append<C::Blob>, name: &[u8]) {
3633
drop(append);
3734
ctx.remove("bench_partition", Some(name)).await.unwrap();
3835
}

runtime/src/utils/buffer/benches/read.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
//! Benchmark read performance at random offsets.
22
33
use super::{create_append, destroy_append, CACHE_SIZE, PAGE_SIZE, PAGE_SIZE_USIZE};
4-
use commonware_runtime::{buffer::paged::CacheRef, deterministic, Runner as _};
4+
use commonware_runtime::{
5+
buffer::paged::CacheRef, deterministic, tokio, BufferPooler, Runner, Storage,
6+
};
57
use commonware_utils::NZUsize;
68
use criterion::Criterion;
79
use rand::{rngs::StdRng, Rng, SeedableRng};
@@ -11,17 +13,21 @@ use std::time::Instant;
1113
const TOTAL_PAGES: usize = CACHE_SIZE;
1214
const TOTAL_SIZE: usize = PAGE_SIZE_USIZE * TOTAL_PAGES;
1315

14-
pub fn bench(c: &mut Criterion) {
15-
for read_size in [64, 256, 1024, 4096] {
16-
let name = format!("read_{read_size}").into_bytes();
17-
18-
c.bench_function(&format!("{}/size={}", module_path!(), read_size), |b| {
16+
fn bench_backend<R>(c: &mut Criterion, backend: &str, read_size: usize)
17+
where
18+
R: Runner + Default,
19+
R::Context: Storage + BufferPooler,
20+
{
21+
c.bench_function(
22+
&format!("{}/backend={backend} size={read_size}", module_path!()),
23+
|b| {
1924
b.iter_custom(|iters| {
20-
let name = name.clone();
25+
let name = format!("read_{backend}_{read_size}").into_bytes();
2126

22-
let executor = deterministic::Runner::default();
27+
let executor = R::default();
2328
executor.start(|ctx| async move {
2429
let cache_ref = CacheRef::from_pooler(&ctx, PAGE_SIZE, NZUsize!(CACHE_SIZE));
30+
2531
// Setup: populate the blob
2632
let append = create_append(&ctx, &name, cache_ref.clone()).await;
2733
let data = vec![0xABu8; TOTAL_SIZE];
@@ -30,7 +36,7 @@ pub fn bench(c: &mut Criterion) {
3036
drop(append);
3137

3238
// Benchmark: random reads
33-
let append = create_append(&ctx, &name, cache_ref.clone()).await;
39+
let append = create_append(&ctx, &name, cache_ref).await;
3440
let mut buf = vec![0u8; read_size];
3541
let max_offset = TOTAL_SIZE - read_size;
3642
let mut rng = StdRng::seed_from_u64(42);
@@ -51,6 +57,13 @@ pub fn bench(c: &mut Criterion) {
5157
elapsed
5258
})
5359
});
54-
});
60+
},
61+
);
62+
}
63+
64+
pub fn bench(c: &mut Criterion) {
65+
for read_size in [64, 256, 1024, 4096] {
66+
bench_backend::<deterministic::Runner>(c, "deterministic", read_size);
67+
bench_backend::<tokio::Runner>(c, "tokio", read_size);
5568
}
5669
}

0 commit comments

Comments
 (0)