From 53e051aa3d279c54fad33b844b63304aa51488ff Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 15 Jan 2024 16:11:25 +0100 Subject: [PATCH] out-of-band stats settings --- crates/re_query_cache/src/cache_stats.rs | 42 +++++----------------- crates/re_query_cache/src/lib.rs | 5 +-- crates/re_viewer/src/app.rs | 3 +- crates/re_viewer/src/ui/memory_panel.rs | 44 +++++++++++++++++------- 4 files changed, 44 insertions(+), 50 deletions(-) diff --git a/crates/re_query_cache/src/cache_stats.rs b/crates/re_query_cache/src/cache_stats.rs index 31e35e8c9ecd..ecf774aa6fb9 100644 --- a/crates/re_query_cache/src/cache_stats.rs +++ b/crates/re_query_cache/src/cache_stats.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, sync::atomic::AtomicBool}; +use std::collections::BTreeMap; use re_log_types::{EntityPath, TimeRange, Timeline}; use re_types_core::ComponentName; @@ -7,34 +7,6 @@ use crate::{Caches, LatestAtCache, RangeCache}; // --- -/// If `true`, enables the much-more-costly-to-compute per-component stats. -static ENABLE_DETAILED_STATS: AtomicBool = AtomicBool::new(false); - -#[inline] -pub fn detailed_stats() -> bool { - ENABLE_DETAILED_STATS.load(std::sync::atomic::Ordering::Relaxed) -} - -#[inline] -pub fn set_detailed_stats(b: bool) { - ENABLE_DETAILED_STATS.store(b, std::sync::atomic::Ordering::Relaxed); -} - -/// If `true`, will show stats about empty caches too, which likely indicates a bug (dangling bucket). -static SHOW_EMPTY_CACHES: AtomicBool = AtomicBool::new(false); - -#[inline] -pub fn show_empty_caches() -> bool { - SHOW_EMPTY_CACHES.load(std::sync::atomic::Ordering::Relaxed) -} - -#[inline] -pub fn set_show_empty_caches(b: bool) { - SHOW_EMPTY_CACHES.store(b, std::sync::atomic::Ordering::Relaxed); -} - -// --- - /// Stats for all primary caches. /// /// Fetch them via [`Caches::stats`]. @@ -72,7 +44,7 @@ pub struct CachedEntityStats { pub total_rows: u64, pub total_size_bytes: u64, - /// Only if [`detailed_stats`] returns `true` (see [`set_detailed_stats`]). + /// Only if `detailed_stats` is `true` (see [`Caches::stats`]). pub per_component: Option>, } @@ -96,7 +68,7 @@ impl Caches { /// Computes the stats for all primary caches. /// /// `per_component` toggles per-component stats. - pub fn stats() -> CachesStats { + pub fn stats(detailed_stats: bool) -> CachesStats { re_tracing::profile_function!(); Self::with(|caches| { @@ -108,7 +80,7 @@ impl Caches { (key.entity_path.clone(), { let mut total_size_bytes = 0u64; let mut total_rows = 0u64; - let mut per_component = detailed_stats().then(BTreeMap::default); + let mut per_component = detailed_stats.then(BTreeMap::default); for latest_at_cache in caches_per_arch.latest_at_per_archetype.read().values() @@ -124,6 +96,8 @@ impl Caches { total_rows = per_data_time.len() as u64 + timeless.is_some() as u64; if let Some(per_component) = per_component.as_mut() { + re_tracing::profile_scope!("detailed"); + for bucket in per_data_time.values() { for (component_name, data) in &bucket.read().components { let stats: &mut CachedComponentStats = @@ -172,8 +146,10 @@ impl Caches { let total_rows = bucket.data_times.len() as u64; - let mut per_component = detailed_stats().then(BTreeMap::default); + let mut per_component = detailed_stats.then(BTreeMap::default); if let Some(per_component) = per_component.as_mut() { + re_tracing::profile_scope!("detailed"); + for (component_name, data) in &bucket.components { let stats: &mut CachedComponentStats = per_component.entry(*component_name).or_default(); diff --git a/crates/re_query_cache/src/lib.rs b/crates/re_query_cache/src/lib.rs index a87bcc681999..fc7f84439f86 100644 --- a/crates/re_query_cache/src/lib.rs +++ b/crates/re_query_cache/src/lib.rs @@ -8,10 +8,7 @@ mod query; mod range; pub use self::cache::{AnyQuery, Caches}; -pub use self::cache_stats::{ - detailed_stats, set_detailed_stats, set_show_empty_caches, show_empty_caches, - CachedComponentStats, CachedEntityStats, CachesStats, -}; +pub use self::cache_stats::{CachedComponentStats, CachedEntityStats, CachesStats}; pub use self::flat_vec_deque::{ErasedFlatVecDeque, FlatVecDeque}; pub use self::query::{ query_archetype_pov1, query_archetype_with_history_pov1, MaybeCachedComponentData, diff --git a/crates/re_viewer/src/app.rs b/crates/re_viewer/src/app.rs index ec8122ae2875..40aa0d1cd32a 100644 --- a/crates/re_viewer/src/app.rs +++ b/crates/re_viewer/src/app.rs @@ -1128,7 +1128,8 @@ impl eframe::App for App { }; let store_stats = store_hub.stats(); - let caches_stats = re_query_cache::Caches::stats(); + let caches_stats = + re_query_cache::Caches::stats(self.memory_panel.primary_cache_detailed_stats_enabled()); // do early, before doing too many allocations self.memory_panel diff --git a/crates/re_viewer/src/ui/memory_panel.rs b/crates/re_viewer/src/ui/memory_panel.rs index 64127e3e225c..156e875826e4 100644 --- a/crates/re_viewer/src/ui/memory_panel.rs +++ b/crates/re_viewer/src/ui/memory_panel.rs @@ -1,3 +1,5 @@ +use std::sync::atomic::AtomicBool; + use re_data_store::{DataStoreConfig, DataStoreRowStats, DataStoreStats}; use re_format::{format_bytes, format_number}; use re_memory::{util::sec_since_start, MemoryHistory, MemoryLimit, MemoryUse}; @@ -12,6 +14,13 @@ use crate::{env_vars::RERUN_TRACK_ALLOCATIONS, store_hub::StoreHubStats}; pub struct MemoryPanel { history: MemoryHistory, memory_purge_times: Vec, + + /// If `true`, enables the much-more-costly-to-compute per-component stats for the primary + /// cache. + prim_cache_detailed_stats: AtomicBool, + + /// If `true`, will show stats about empty primary caches too, which likely indicates a bug (dangling bucket). + prim_cache_show_empty: AtomicBool, } impl MemoryPanel { @@ -35,10 +44,17 @@ impl MemoryPanel { } /// Note that we purged memory at this time, to show in stats. + #[inline] pub fn note_memory_purge(&mut self) { self.memory_purge_times.push(sec_since_start()); } + #[inline] + pub fn primary_cache_detailed_stats_enabled(&self) -> bool { + self.prim_cache_detailed_stats + .load(std::sync::atomic::Ordering::Relaxed) + } + #[allow(clippy::too_many_arguments)] pub fn ui( &self, @@ -59,7 +75,7 @@ impl MemoryPanel { .min_width(250.0) .default_width(300.0) .show_inside(ui, |ui| { - Self::left_side( + self.left_side( ui, re_ui, limit, @@ -76,6 +92,7 @@ impl MemoryPanel { } fn left_side( + &self, ui: &mut egui::Ui, re_ui: &re_ui::ReUi, limit: &MemoryLimit, @@ -106,7 +123,7 @@ impl MemoryPanel { ui.separator(); ui.collapsing("Primary Cache Resources", |ui| { - Self::caches_stats(ui, re_ui, caches_stats); + self.caches_stats(ui, re_ui, caches_stats); }); ui.separator(); @@ -309,24 +326,27 @@ impl MemoryPanel { }); } - fn caches_stats(ui: &mut egui::Ui, re_ui: &re_ui::ReUi, caches_stats: &CachesStats) { - let mut detailed_stats = re_query_cache::detailed_stats(); + fn caches_stats(&self, ui: &mut egui::Ui, re_ui: &re_ui::ReUi, caches_stats: &CachesStats) { + use std::sync::atomic::Ordering::Relaxed; + + let mut detailed_stats = self.prim_cache_detailed_stats.load(Relaxed); re_ui .checkbox(ui, &mut detailed_stats, "Detailed stats") .on_hover_text("Show detailed statistics when hovering entity paths below.\nThis will slow down the program."); - re_query_cache::set_detailed_stats(detailed_stats); + self.prim_cache_detailed_stats + .store(detailed_stats, Relaxed); - let mut show_empty_caches = re_query_cache::show_empty_caches(); + let mut show_empty = self.prim_cache_show_empty.load(Relaxed); re_ui - .checkbox(ui, &mut show_empty_caches, "Show empty caches") + .checkbox(ui, &mut show_empty, "Show empty caches") .on_hover_text( "Show empty caches too.\nDangling buckets are generally the result of a bug.", ); - re_query_cache::set_show_empty_caches(show_empty_caches); + self.prim_cache_show_empty.store(show_empty, Relaxed); let CachesStats { latest_at, range } = caches_stats; - if show_empty_caches || !latest_at.is_empty() { + if show_empty || !latest_at.is_empty() { ui.separator(); ui.strong("LatestAt"); egui::ScrollArea::vertical() @@ -345,7 +365,7 @@ impl MemoryPanel { ui.end_row(); for (entity_path, stats) in latest_at { - if !show_empty_caches && stats.is_empty() { + if !show_empty && stats.is_empty() { continue; } @@ -357,7 +377,7 @@ impl MemoryPanel { }); } - if show_empty_caches || !latest_at.is_empty() { + if show_empty || !latest_at.is_empty() { ui.separator(); ui.strong("Range"); egui::ScrollArea::vertical() @@ -378,7 +398,7 @@ impl MemoryPanel { for (entity_path, stats_per_range) in range { for (timeline, time_range, stats) in stats_per_range { - if !show_empty_caches && stats.is_empty() { + if !show_empty && stats.is_empty() { continue; }