From eeb14b25c6f7705a6fbfce296b961c7f95f1eb18 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 1 Oct 2025 08:48:02 +0300 Subject: [PATCH] perf/throughput: Replace think time with CPU-bound compute time Replace the sleep-based --think parameter with a --compute parameter that uses a busy loop to simulate realistic CPU or GPU bound business logic (e.g., parsing, data aggregation, or ML inference). The compute time is now specified in microseconds instead of milliseconds for finer granularity. --- perf/throughput/rusqlite/src/main.rs | 32 +++++++++++++++++++++------- perf/throughput/turso/src/main.rs | 32 +++++++++++++++++++--------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/perf/throughput/rusqlite/src/main.rs b/perf/throughput/rusqlite/src/main.rs index 1dd518270..af54b8818 100644 --- a/perf/throughput/rusqlite/src/main.rs +++ b/perf/throughput/rusqlite/src/main.rs @@ -18,11 +18,11 @@ struct Args { iterations: usize, #[arg( - long = "think", + long = "compute", default_value = "0", - help = "Per transaction think time (ms)" + help = "Per transaction compute time (us)" )] - think: u64, + compute: u64, } fn main() -> Result<()> { @@ -61,7 +61,7 @@ fn main() -> Result<()> { args.batch_size, args.iterations, barrier, - args.think, + args.compute, ) }); @@ -126,7 +126,7 @@ fn worker_thread( batch_size: usize, iterations: usize, start_barrier: Arc, - think_ms: u64, + compute_usec: u64, ) -> Result { let conn = Connection::open(&db_path)?; @@ -142,14 +142,16 @@ fn worker_thread( conn.execute("BEGIN", [])?; + let result = perform_compute(thread_id, compute_usec); + + std::hint::black_box(result); + for i in 0..batch_size { let id = thread_id * iterations * batch_size + iteration * batch_size + i; stmt.execute([&id.to_string(), &format!("data_{id}")])?; total_inserts += 1; } - if think_ms > 0 { - thread::sleep(std::time::Duration::from_millis(think_ms)); - } + conn.execute("COMMIT", [])?; } @@ -166,3 +168,17 @@ fn worker_thread( Ok(total_inserts) } + +// Busy loop to simulate CPU or GPU bound computation (for example, parsing, +// data aggregation or ML inference). +fn perform_compute(thread_id: usize, usec: u64) -> u64 { + if usec == 0 { + return 0; + } + let start = Instant::now(); + let mut sum: u64 = 0; + while start.elapsed().as_micros() < usec as u128 { + sum = sum.wrapping_add(thread_id as u64); + } + sum +} diff --git a/perf/throughput/turso/src/main.rs b/perf/throughput/turso/src/main.rs index 409f68f80..745b392d1 100644 --- a/perf/throughput/turso/src/main.rs +++ b/perf/throughput/turso/src/main.rs @@ -35,11 +35,11 @@ struct Args { mode: TransactionMode, #[arg( - long = "think", + long = "compute", default_value = "0", - help = "Per transaction think time (ms)" + help = "Per transaction compute time (us)" )] - think: u64, + compute: u64, #[arg( long = "timeout", @@ -95,7 +95,7 @@ async fn main() -> Result<()> { args.iterations, barrier, args.mode, - args.think, + args.compute, timeout, )); @@ -171,7 +171,6 @@ async fn setup_database( ) .await?; - println!("Database created at: {db_path}"); Ok(db) } @@ -183,7 +182,7 @@ async fn worker_thread( iterations: usize, start_barrier: Arc, mode: TransactionMode, - think_ms: u64, + compute_usec: u64, timeout: Duration, ) -> Result { start_barrier.wait(); @@ -208,6 +207,9 @@ async fn worker_thread( }; conn.execute(begin_stmt, ()).await?; + let result = perform_compute(thread_id, compute_usec); + std::hint::black_box(result); + for i in 0..batch_size { let id = thread_id * iterations * batch_size + iteration * batch_size + i; stmt.execute(turso::params::Params::Positional(vec![ @@ -218,10 +220,6 @@ async fn worker_thread( total_inserts.fetch_add(1, Ordering::Relaxed); } - if think_ms > 0 { - tokio::time::sleep(tokio::time::Duration::from_millis(think_ms)).await; - } - conn.execute("COMMIT", ()).await?; Ok::<_, turso::Error>(()) }; @@ -250,3 +248,17 @@ async fn worker_thread( Ok(final_inserts) } + +// Busy loop to simulate CPU or GPU bound computation (for example, parsing, +// data aggregation or ML inference). +fn perform_compute(thread_id: usize, usec: u64) -> u64 { + if usec == 0 { + return 0; + } + let start = Instant::now(); + let mut sum: u64 = 0; + while start.elapsed().as_micros() < usec as u128 { + sum = sum.wrapping_add(thread_id as u64); + } + sum +}