From aabf67a72a3c80af00f6f01a63592c5743b6ac3b Mon Sep 17 00:00:00 2001 From: Imbris Date: Wed, 14 Jun 2023 02:45:39 -0400 Subject: [PATCH 1/4] Add server-cli bench command for profiling that automates loading a certain area, running for a specific time, and then exiting. --- server-cli/src/cli.rs | 13 +++++++++++++ server-cli/src/main.rs | 38 +++++++++++++++++++++++++++++++------- server/src/lib.rs | 9 +++++++++ server/src/sys/metrics.rs | 22 +++++++++++++++------- 4 files changed, 68 insertions(+), 14 deletions(-) diff --git a/server-cli/src/cli.rs b/server-cli/src/cli.rs index f383cbf9fa..239e40967c 100644 --- a/server-cli/src/cli.rs +++ b/server-cli/src/cli.rs @@ -82,10 +82,23 @@ pub struct TuiApp { command: Message, } +#[derive(Debug, Clone, Copy, Parser)] +pub struct BenchParams { + /// View distance of the loaded area (in chunks) + #[arg(long)] + pub view_distance: u32, + /// Duration to run after loading completes (in seconds). + #[arg(long)] + pub duration: u32, +} + #[derive(Parser)] pub enum ArgvCommand { #[command(flatten)] Shared(SharedCommand), + /// Load an area, run the server for some time, and then exit (useful for + /// profiling). + Bench(BenchParams), } #[derive(Parser)] diff --git a/server-cli/src/main.rs b/server-cli/src/main.rs index 7074177400..ea5d7346cd 100644 --- a/server-cli/src/main.rs +++ b/server-cli/src/main.rs @@ -29,7 +29,7 @@ use server::{persistence::DatabaseSettings, settings::Protocol, Event, Input, Se use std::{ io, sync::{atomic::AtomicBool, mpsc, Arc}, - time::Duration, + time::{Duration, Instant}, }; use tracing::{info, trace}; @@ -117,15 +117,16 @@ fn main() -> io::Result<()> { sql_log_mode, }; + let mut bench = None; if let Some(command) = app.command { - return match command { + match command { ArgvCommand::Shared(SharedCommand::Admin { command }) => { let login_provider = server::login_provider::LoginProvider::new( server_settings.auth_server_address, runtime, ); - match command { + return match command { Admin::Add { username, role } => { // FIXME: Currently the UUID can get returned even if the file didn't // change, so this can't be relied on as an error @@ -139,6 +140,7 @@ fn main() -> io::Result<()> { &mut editable_settings, &server_data_dir, ); + Ok(()) }, Admin::Remove { username } => { // FIXME: Currently the UUID can get returned even if the file didn't @@ -152,9 +154,15 @@ fn main() -> io::Result<()> { &mut editable_settings, &server_data_dir, ); + Ok(()) }, - } - Ok(()) + }; + }, + ArgvCommand::Bench(params) => { + bench = Some(params); + // If we are trying to benchmark, don't limit the server view distance. + server_settings.max_view_distance = None; + // TODO: add setting to adjust entity spawn density }, }; } @@ -207,12 +215,28 @@ fn main() -> io::Result<()> { // Set up an fps clock let mut clock = Clock::new(Duration::from_secs_f64(1.0 / TPS as f64)); - // Wait for a tick so we don't start with a zero dt + + if let Some(bench) = bench { + #[cfg(feature = "worldgen")] + server.create_centered_persister(bench.view_distance); + } + let mut bench_exit_time = None; let mut tick_no = 0u64; loop { - tick_no += 1; span!(guard, "work"); + if let Some(bench) = bench { + if let Some(t) = bench_exit_time { + if Instant::now() > t { + break; + } + } else if tick_no != 0 && !server.chunks_pending() { + println!("Chunk loading complete"); + bench_exit_time = Some(Instant::now() + Duration::from_secs(bench.duration.into())); + } + }; + + tick_no += 1; // Terminate the server if instructed to do so by the shutdown coordinator if shutdown_coordinator.check(&mut server, &settings) { break; diff --git a/server/src/lib.rs b/server/src/lib.rs index 491d70ed17..5cb4ad5123 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1442,6 +1442,15 @@ impl Server { .build(); } + /// Used by benchmarking code. + pub fn chunks_pending(&mut self) -> bool { + self.state_mut() + .mut_resource::() + .pending_chunks() + .next() + .is_some() + } + /// Sets the SQL log mode at runtime pub fn set_sql_log_mode(&mut self, sql_log_mode: SqlLogMode) { // Unwrap is safe here because we only perform a variable assignment with the diff --git a/server/src/sys/metrics.rs b/server/src/sys/metrics.rs index 07c79dfd22..d8633805cc 100644 --- a/server/src/sys/metrics.rs +++ b/server/src/sys/metrics.rs @@ -1,4 +1,5 @@ use crate::{ + chunk_generator::ChunkGenerator, metrics::{EcsSystemMetrics, JobMetrics, PhysicsMetrics, TickMetrics}, HwStats, Tick, TickStart, }; @@ -12,11 +13,12 @@ use std::time::Instant; pub struct Sys; impl<'a> System<'a> for Sys { type SystemData = ( - Option>, + Entities<'a>, ReadExpect<'a, HwStats>, ReadExpect<'a, Tick>, ReadExpect<'a, TimeOfDay>, ReadExpect<'a, TickStart>, + ReadExpect<'a, ChunkGenerator>, Option>, Read<'a, SysMetrics>, Read<'a, common_ecs::PhysicsMetrics>, @@ -39,6 +41,7 @@ impl<'a> System<'a> for Sys { tick, time_of_day, tick_start, + chunk_generator, terrain, sys_metrics, phys_metrics, @@ -89,7 +92,7 @@ impl<'a> System<'a> for Sys { // Report other info export_tick.time_of_day.set(time_of_day.0); if tick.0.rem_euclid(100) == 0 { - if let Some(terrain) = terrain { + if let Some(terrain) = terrain.as_ref() { let mut chonk_cnt = 0; let mut group_cnt = 0; let chunk_cnt = terrain.iter().fold(0, |a, (_, c)| { @@ -102,11 +105,16 @@ impl<'a> System<'a> for Sys { export_tick.chunk_groups_count.set(group_cnt as i64); } - if let Some(entities) = entities { - let entity_count = entities.join().count(); - export_tick.entity_count.set(entity_count as i64); - common_base::plot!("entity count", entity_count as f64); - } + let entity_count = entities.join().count(); + export_tick.entity_count.set(entity_count as i64); + } + common_base::plot!("entity count", entities.join().count() as f64); + common_base::plot!( + "pending chunks", + chunk_generator.pending_chunks().count() as f64 + ); + if let Some(terrain) = terrain.as_ref() { + common_base::plot!("chunk count", terrain.iter().count() as f64); } //detailed physics metrics From afe97f4d670b02fbb13354a0697e178442086944 Mon Sep 17 00:00:00 2001 From: Imbris Date: Thu, 14 Sep 2023 22:15:08 -0400 Subject: [PATCH 2/4] Make sure we use one version of tracy-client!!!!! --- Cargo.lock | 19 ++++--------------- common/frontend/Cargo.toml | 3 ++- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de850eb772..6cf2b9790c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4588,7 +4588,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "332cd62e95873ea4f41f3dfd6bbbfc5b52aec892d7e8d534197c4720a0bbbab2" dependencies = [ "profiling-procmacros", - "tracy-client 0.15.2", + "tracy-client", ] [[package]] @@ -6532,13 +6532,13 @@ dependencies = [ [[package]] name = "tracing-tracy" -version = "0.10.3" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3edd27f53bc0e55aefa9223f68eb44354060103d3e34635f6e27627fe0227f" +checksum = "55c48ef3e655220d4e43a6be44aa84f078c3004357251cab45f9cc15551a593e" dependencies = [ "tracing-core", "tracing-subscriber", - "tracy-client 0.16.1", + "tracy-client", ] [[package]] @@ -6552,17 +6552,6 @@ dependencies = [ "tracy-client-sys", ] -[[package]] -name = "tracy-client" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c78458aa3759647e0399e959a06f9f6dc61450a1caaa4f1632a3df8e8c55af7" -dependencies = [ - "loom", - "once_cell", - "tracy-client-sys", -] - [[package]] name = "tracy-client-sys" version = "0.21.1" diff --git a/common/frontend/Cargo.toml b/common/frontend/Cargo.toml index 244cf9b4db..4f1fe6b3a5 100644 --- a/common/frontend/Cargo.toml +++ b/common/frontend/Cargo.toml @@ -20,4 +20,5 @@ tracing-subscriber = { version = "0.3.7", default-features = false, features = [ # Tracy # NOTE: This must be kept in sync with the `profiling` version in `common/base`. -tracing-tracy = { version = "0.10.2", optional = true } +# NOTE: `=` since the minor version of tracing-tracy bumped a major version of `tracy-client` +tracing-tracy = { version = "=0.10.2", optional = true } From cd29170beacf85cbfe0c87c7aafa0ff9a31f7f31 Mon Sep 17 00:00:00 2001 From: Imbris Date: Thu, 14 Sep 2023 22:59:16 -0400 Subject: [PATCH 3/4] Update todo about wildlife density option --- server-cli/src/main.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server-cli/src/main.rs b/server-cli/src/main.rs index ea5d7346cd..c3e6cf2092 100644 --- a/server-cli/src/main.rs +++ b/server-cli/src/main.rs @@ -162,7 +162,10 @@ fn main() -> io::Result<()> { bench = Some(params); // If we are trying to benchmark, don't limit the server view distance. server_settings.max_view_distance = None; - // TODO: add setting to adjust entity spawn density + // TODO: add setting to adjust wildlife spawn density, note I + // tried but Index setup makes it a bit + // annoying, might require a more involved refactor to get + // working nicely }, }; } From b9731b57cee4524e5964259d8e38e3757b0312b4 Mon Sep 17 00:00:00 2001 From: Imbris Date: Thu, 14 Sep 2023 23:42:52 -0400 Subject: [PATCH 4/4] Update to specs 0.19 --- Cargo.lock | 19 ++++++------------- Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6cf2b9790c..a5d2f155ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3600,12 +3600,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "mopa" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a785740271256c230f57462d3b83e52f998433a7062fc18f96d5999474a9f915" - [[package]] name = "more-asserts" version = "0.2.2" @@ -5685,13 +5679,12 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "shred" -version = "0.13.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102269e720bb814df57e136161cad841f2b6f411e003ac748fc48aaf2363bea3" +checksum = "d6aa4148ce950f367ede79bff6bb04bbf3c31317a1291315078ef60c080821a1" dependencies = [ + "ahash 0.7.6", "arrayvec 0.7.4", - "hashbrown 0.12.3", - "mopa", "rayon", "shred-derive", "smallvec", @@ -5862,12 +5855,12 @@ dependencies = [ [[package]] name = "specs" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea85dac2880f84d4025ff5ace80cda6d8bc43bc88b6a389b9277fcf894b51e9" +checksum = "ad2e89cb8aba27bebf48a5a47b4889e7b317a08884d92cc36109d58992d41325" dependencies = [ + "ahash 0.7.6", "crossbeam-queue", - "hashbrown 0.12.3", "hibitset", "log", "rayon", diff --git a/Cargo.toml b/Cargo.toml index 79dbbdd4eb..ceb2aa77af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -149,7 +149,7 @@ serde = { version = "1.0.118", features = ["derive"] } serde_json = { version = "1.0.50" } ron = { version = "0.8", default-features = false} -specs = { version = "0.18", features = ["nightly"] } +specs = { version = "0.19", features = ["nightly"] } image = { version = "0.24", default-features = false, features = ["png"] } rayon = { version = "1.5" }