From 674ebbfdc1fc9240dccbdd0bf459eed8e3882ce9 Mon Sep 17 00:00:00 2001 From: koe Date: Thu, 21 Sep 2023 07:38:36 -0500 Subject: [PATCH 1/3] spin in benches instead of yielding --- Cargo.toml | 1 + benches/replication.rs | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dd2fda93..b07c42f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ serde_test = "1.0" criterion = { version = "0.5", default-features = false, features = [ "cargo_bench_support", ] } +spin_sleep = "1.1" anyhow = "1.0" clap = { version = "4.1", features = ["derive"] } bevy = { version = "0.11", default-features = false, features = [ diff --git a/benches/replication.rs b/benches/replication.rs index 7e0d213f..41fb2281 100644 --- a/benches/replication.rs +++ b/benches/replication.rs @@ -18,6 +18,8 @@ fn replication(c: &mut Criterion) { c.bench_function("entities send", |b| { b.iter_custom(|iter| { let mut elapsed = Duration::ZERO; + let sleeper = spin_sleep::SpinSleeper::new(1_000_000_000) + .with_spin_strategy(spin_sleep::SpinStrategy::SpinLoopHint); for _ in 0..iter { let mut server_app = App::new(); let mut client_app = App::new(); @@ -34,7 +36,7 @@ fn replication(c: &mut Criterion) { server_app.update(); elapsed += instant.elapsed(); - std::thread::sleep(SOCKET_WAIT); + sleeper.sleep(SOCKET_WAIT); client_app.update(); assert_eq!(client_app.world.entities().len(), ENTITIES); } @@ -46,6 +48,8 @@ fn replication(c: &mut Criterion) { c.bench_function("entities receive", |b| { b.iter_custom(|iter| { let mut elapsed = Duration::ZERO; + let sleeper = spin_sleep::SpinSleeper::new(1_000_000_000) + .with_spin_strategy(spin_sleep::SpinStrategy::SpinLoopHint); for _ in 0..iter { let mut server_app = App::new(); let mut client_app = App::new(); @@ -59,7 +63,7 @@ fn replication(c: &mut Criterion) { .spawn_batch([(Replication, DummyComponent(0)); ENTITIES as usize]); server_app.update(); - std::thread::sleep(SOCKET_WAIT); + sleeper.sleep(SOCKET_WAIT); let instant = Instant::now(); client_app.update(); @@ -74,6 +78,8 @@ fn replication(c: &mut Criterion) { c.bench_function("entities update send", |b| { b.iter_custom(|iter| { let mut elapsed = Duration::ZERO; + let sleeper = spin_sleep::SpinSleeper::new(1_000_000_000) + .with_spin_strategy(spin_sleep::SpinStrategy::SpinLoopHint); let mut server_app = App::new(); let mut client_app = App::new(); for app in [&mut server_app, &mut client_app] { @@ -87,7 +93,7 @@ fn replication(c: &mut Criterion) { let mut query = server_app.world.query::<&mut DummyComponent>(); server_app.update(); - std::thread::sleep(SOCKET_WAIT); + sleeper.sleep(SOCKET_WAIT); client_app.update(); assert_eq!(client_app.world.entities().len(), ENTITIES); @@ -96,12 +102,12 @@ fn replication(c: &mut Criterion) { dummy_component.0 += 1; } - std::thread::sleep(SOCKET_WAIT); + sleeper.sleep(SOCKET_WAIT); let instant = Instant::now(); server_app.update(); elapsed += instant.elapsed(); - std::thread::sleep(SOCKET_WAIT); + sleeper.sleep(SOCKET_WAIT); client_app.update(); assert_eq!(client_app.world.entities().len(), ENTITIES); } @@ -113,6 +119,8 @@ fn replication(c: &mut Criterion) { c.bench_function("entities update receive", |b| { b.iter_custom(|iter| { let mut elapsed = Duration::ZERO; + let sleeper = spin_sleep::SpinSleeper::new(1_000_000_000) + .with_spin_strategy(spin_sleep::SpinStrategy::SpinLoopHint); let mut server_app = App::new(); let mut client_app = App::new(); for app in [&mut server_app, &mut client_app] { @@ -126,7 +134,7 @@ fn replication(c: &mut Criterion) { let mut query = server_app.world.query::<&mut DummyComponent>(); server_app.update(); - std::thread::sleep(SOCKET_WAIT); + sleeper.sleep(SOCKET_WAIT); client_app.update(); assert_eq!(client_app.world.entities().len(), ENTITIES); @@ -135,9 +143,9 @@ fn replication(c: &mut Criterion) { dummy_component.0 += 1; } - std::thread::sleep(SOCKET_WAIT); + sleeper.sleep(SOCKET_WAIT); server_app.update(); - std::thread::sleep(SOCKET_WAIT); + sleeper.sleep(SOCKET_WAIT); let instant = Instant::now(); client_app.update(); From f7fa221f8ade71c4a520463d38a8b5a5005ccef8 Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Thu, 21 Sep 2023 15:48:48 +0300 Subject: [PATCH 2/3] Create sleeper once --- benches/replication.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/benches/replication.rs b/benches/replication.rs index 41fb2281..cfff2662 100644 --- a/benches/replication.rs +++ b/benches/replication.rs @@ -7,6 +7,7 @@ use bevy::{app::MainScheduleOrder, ecs::schedule::ExecutorKind, prelude::*}; use bevy_replicon::prelude::*; use criterion::{criterion_group, criterion_main, Criterion}; use serde::{Deserialize, Serialize}; +use spin_sleep::{SpinSleeper, SpinStrategy}; #[derive(Component, Clone, Copy, Serialize, Deserialize)] struct DummyComponent(usize); @@ -15,11 +16,12 @@ const ENTITIES: u32 = 900; const SOCKET_WAIT: Duration = Duration::from_millis(5); // Sometimes it takes time for socket to receive all data. fn replication(c: &mut Criterion) { + // Use spinner to keep CPU hot in the schedule for stable benchmark results. + let sleeper = SpinSleeper::new(1_000_000_000).with_spin_strategy(SpinStrategy::SpinLoopHint); + c.bench_function("entities send", |b| { b.iter_custom(|iter| { let mut elapsed = Duration::ZERO; - let sleeper = spin_sleep::SpinSleeper::new(1_000_000_000) - .with_spin_strategy(spin_sleep::SpinStrategy::SpinLoopHint); for _ in 0..iter { let mut server_app = App::new(); let mut client_app = App::new(); @@ -48,8 +50,6 @@ fn replication(c: &mut Criterion) { c.bench_function("entities receive", |b| { b.iter_custom(|iter| { let mut elapsed = Duration::ZERO; - let sleeper = spin_sleep::SpinSleeper::new(1_000_000_000) - .with_spin_strategy(spin_sleep::SpinStrategy::SpinLoopHint); for _ in 0..iter { let mut server_app = App::new(); let mut client_app = App::new(); @@ -78,8 +78,6 @@ fn replication(c: &mut Criterion) { c.bench_function("entities update send", |b| { b.iter_custom(|iter| { let mut elapsed = Duration::ZERO; - let sleeper = spin_sleep::SpinSleeper::new(1_000_000_000) - .with_spin_strategy(spin_sleep::SpinStrategy::SpinLoopHint); let mut server_app = App::new(); let mut client_app = App::new(); for app in [&mut server_app, &mut client_app] { @@ -119,8 +117,6 @@ fn replication(c: &mut Criterion) { c.bench_function("entities update receive", |b| { b.iter_custom(|iter| { let mut elapsed = Duration::ZERO; - let sleeper = spin_sleep::SpinSleeper::new(1_000_000_000) - .with_spin_strategy(spin_sleep::SpinStrategy::SpinLoopHint); let mut server_app = App::new(); let mut client_app = App::new(); for app in [&mut server_app, &mut client_app] { From 4213ca5d420fa6e8d9c47c2c9eaa52f53baf1f49 Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Thu, 21 Sep 2023 15:49:50 +0300 Subject: [PATCH 3/3] Put other constants under `replication` benchmark fn --- benches/replication.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/benches/replication.rs b/benches/replication.rs index cfff2662..1dc71e49 100644 --- a/benches/replication.rs +++ b/benches/replication.rs @@ -12,10 +12,10 @@ use spin_sleep::{SpinSleeper, SpinStrategy}; #[derive(Component, Clone, Copy, Serialize, Deserialize)] struct DummyComponent(usize); -const ENTITIES: u32 = 900; -const SOCKET_WAIT: Duration = Duration::from_millis(5); // Sometimes it takes time for socket to receive all data. - fn replication(c: &mut Criterion) { + const ENTITIES: u32 = 900; + const SOCKET_WAIT: Duration = Duration::from_millis(5); // Sometimes it takes time for socket to receive all data. + // Use spinner to keep CPU hot in the schedule for stable benchmark results. let sleeper = SpinSleeper::new(1_000_000_000).with_spin_strategy(SpinStrategy::SpinLoopHint);