benches: use criterion instead of bencher (#5981)

This commit is contained in:
M.Amin Rayej
2023-09-10 16:42:53 +02:00
committed by GitHub
parent 737dff40cb
commit b046c0dcbb
14 changed files with 779 additions and 646 deletions
+117 -104
View File
@@ -5,63 +5,68 @@
use tokio::runtime::{self, Runtime};
use tokio::sync::oneshot;
use bencher::{benchmark_group, benchmark_main, Bencher};
use std::sync::atomic::Ordering::Relaxed;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::{mpsc, Arc};
use std::time::{Duration, Instant};
use criterion::{criterion_group, criterion_main, Criterion};
const NUM_WORKERS: usize = 4;
const NUM_SPAWN: usize = 10_000;
const STALL_DUR: Duration = Duration::from_micros(10);
fn spawn_many_local(b: &mut Bencher) {
fn spawn_many_local(c: &mut Criterion) {
let rt = rt();
let (tx, rx) = mpsc::sync_channel(1000);
let rem = Arc::new(AtomicUsize::new(0));
b.iter(|| {
rem.store(NUM_SPAWN, Relaxed);
c.bench_function("spawn_many_local", |b| {
b.iter(|| {
rem.store(NUM_SPAWN, Relaxed);
rt.block_on(async {
for _ in 0..NUM_SPAWN {
let tx = tx.clone();
let rem = rem.clone();
rt.block_on(async {
for _ in 0..NUM_SPAWN {
let tx = tx.clone();
let rem = rem.clone();
tokio::spawn(async move {
if 1 == rem.fetch_sub(1, Relaxed) {
tx.send(()).unwrap();
}
});
}
tokio::spawn(async move {
if 1 == rem.fetch_sub(1, Relaxed) {
tx.send(()).unwrap();
}
});
}
let _ = rx.recv().unwrap();
});
let _ = rx.recv().unwrap();
});
})
});
}
fn spawn_many_remote_idle(b: &mut Bencher) {
fn spawn_many_remote_idle(c: &mut Criterion) {
let rt = rt();
let mut handles = Vec::with_capacity(NUM_SPAWN);
b.iter(|| {
for _ in 0..NUM_SPAWN {
handles.push(rt.spawn(async {}));
}
rt.block_on(async {
for handle in handles.drain(..) {
handle.await.unwrap();
c.bench_function("spawn_many_remote_idle", |b| {
b.iter(|| {
for _ in 0..NUM_SPAWN {
handles.push(rt.spawn(async {}));
}
});
rt.block_on(async {
for handle in handles.drain(..) {
handle.await.unwrap();
}
});
})
});
}
// The runtime is busy with tasks that consume CPU time and yield. Yielding is a
// lower notification priority than spawning / regular notification.
fn spawn_many_remote_busy1(b: &mut Bencher) {
fn spawn_many_remote_busy1(c: &mut Criterion) {
let rt = rt();
let rt_handle = rt.handle();
let mut handles = Vec::with_capacity(NUM_SPAWN);
@@ -78,16 +83,18 @@ fn spawn_many_remote_busy1(b: &mut Bencher) {
});
}
b.iter(|| {
for _ in 0..NUM_SPAWN {
handles.push(rt_handle.spawn(async {}));
}
rt.block_on(async {
for handle in handles.drain(..) {
handle.await.unwrap();
c.bench_function("spawn_many_remote_busy1", |b| {
b.iter(|| {
for _ in 0..NUM_SPAWN {
handles.push(rt_handle.spawn(async {}));
}
});
rt.block_on(async {
for handle in handles.drain(..) {
handle.await.unwrap();
}
});
})
});
flag.store(false, Relaxed);
@@ -95,7 +102,7 @@ fn spawn_many_remote_busy1(b: &mut Bencher) {
// The runtime is busy with tasks that consume CPU time and spawn new high-CPU
// tasks. Spawning goes via a higher notification priority than yielding.
fn spawn_many_remote_busy2(b: &mut Bencher) {
fn spawn_many_remote_busy2(c: &mut Criterion) {
const NUM_SPAWN: usize = 1_000;
let rt = rt();
@@ -119,49 +126,52 @@ fn spawn_many_remote_busy2(b: &mut Bencher) {
});
}
b.iter(|| {
for _ in 0..NUM_SPAWN {
handles.push(rt_handle.spawn(async {}));
}
rt.block_on(async {
for handle in handles.drain(..) {
handle.await.unwrap();
c.bench_function("spawn_many_remote_busy2", |b| {
b.iter(|| {
for _ in 0..NUM_SPAWN {
handles.push(rt_handle.spawn(async {}));
}
});
rt.block_on(async {
for handle in handles.drain(..) {
handle.await.unwrap();
}
});
})
});
flag.store(false, Relaxed);
}
fn yield_many(b: &mut Bencher) {
fn yield_many(c: &mut Criterion) {
const NUM_YIELD: usize = 1_000;
const TASKS: usize = 200;
let rt = rt();
c.bench_function("yield_many", |b| {
let rt = rt();
let (tx, rx) = mpsc::sync_channel(TASKS);
let (tx, rx) = mpsc::sync_channel(TASKS);
b.iter(move || {
for _ in 0..TASKS {
let tx = tx.clone();
b.iter(move || {
for _ in 0..TASKS {
let tx = tx.clone();
rt.spawn(async move {
for _ in 0..NUM_YIELD {
tokio::task::yield_now().await;
}
rt.spawn(async move {
for _ in 0..NUM_YIELD {
tokio::task::yield_now().await;
}
tx.send(()).unwrap();
});
}
tx.send(()).unwrap();
});
}
for _ in 0..TASKS {
let _ = rx.recv().unwrap();
}
for _ in 0..TASKS {
let _ = rx.recv().unwrap();
}
})
});
}
fn ping_pong(b: &mut Bencher) {
fn ping_pong(c: &mut Criterion) {
const NUM_PINGS: usize = 1_000;
let rt = rt();
@@ -169,46 +179,46 @@ fn ping_pong(b: &mut Bencher) {
let (done_tx, done_rx) = mpsc::sync_channel(1000);
let rem = Arc::new(AtomicUsize::new(0));
b.iter(|| {
let done_tx = done_tx.clone();
let rem = rem.clone();
rem.store(NUM_PINGS, Relaxed);
c.bench_function("ping_pong", |b| {
b.iter(|| {
let done_tx = done_tx.clone();
let rem = rem.clone();
rem.store(NUM_PINGS, Relaxed);
rt.block_on(async {
tokio::spawn(async move {
for _ in 0..NUM_PINGS {
let rem = rem.clone();
let done_tx = done_tx.clone();
tokio::spawn(async move {
let (tx1, rx1) = oneshot::channel();
let (tx2, rx2) = oneshot::channel();
rt.block_on(async {
tokio::spawn(async move {
for _ in 0..NUM_PINGS {
let rem = rem.clone();
let done_tx = done_tx.clone();
tokio::spawn(async move {
rx1.await.unwrap();
tx2.send(()).unwrap();
let (tx1, rx1) = oneshot::channel();
let (tx2, rx2) = oneshot::channel();
tokio::spawn(async move {
rx1.await.unwrap();
tx2.send(()).unwrap();
});
tx1.send(()).unwrap();
rx2.await.unwrap();
if 1 == rem.fetch_sub(1, Relaxed) {
done_tx.send(()).unwrap();
}
});
}
});
tx1.send(()).unwrap();
rx2.await.unwrap();
if 1 == rem.fetch_sub(1, Relaxed) {
done_tx.send(()).unwrap();
}
});
}
done_rx.recv().unwrap();
});
done_rx.recv().unwrap();
});
})
});
}
fn chained_spawn(b: &mut Bencher) {
fn chained_spawn(c: &mut Criterion) {
const ITER: usize = 1_000;
let rt = rt();
fn iter(done_tx: mpsc::SyncSender<()>, n: usize) {
if n == 0 {
done_tx.send(()).unwrap();
@@ -219,18 +229,21 @@ fn chained_spawn(b: &mut Bencher) {
}
}
let (done_tx, done_rx) = mpsc::sync_channel(1000);
c.bench_function("chained_spawn", |b| {
let rt = rt();
let (done_tx, done_rx) = mpsc::sync_channel(1000);
b.iter(move || {
let done_tx = done_tx.clone();
b.iter(move || {
let done_tx = done_tx.clone();
rt.block_on(async {
tokio::spawn(async move {
iter(done_tx, ITER);
rt.block_on(async {
tokio::spawn(async move {
iter(done_tx, ITER);
});
done_rx.recv().unwrap();
});
done_rx.recv().unwrap();
});
})
});
}
@@ -249,7 +262,7 @@ fn stall() {
}
}
benchmark_group!(
criterion_group!(
scheduler,
spawn_many_local,
spawn_many_remote_idle,
@@ -260,4 +273,4 @@ benchmark_group!(
chained_spawn,
);
benchmark_main!(scheduler);
criterion_main!(scheduler);