From c7f50ec3e0d06816cf8248d0b044c0597a4ff4d4 Mon Sep 17 00:00:00 2001 From: Federico Lolli <federico.lolli@skywarder.eu> Date: Mon, 3 Mar 2025 17:53:27 +0100 Subject: [PATCH] Added profiler --- Cargo.lock | 74 +++++++++++++++++++++ Cargo.toml | 8 +-- src/main.rs | 5 +- src/mavlink/base.rs | 1 + src/message_broker.rs | 6 +- src/ui/composable_view.rs | 7 ++ src/ui/panes/default.rs | 3 +- src/ui/panes/messages_viewer.rs | 1 + src/ui/panes/plot.rs | 6 +- src/ui/panes/plot/source_window.rs | 3 +- src/ui/persistency/layout_manager.rs | 3 + src/ui/persistency/layout_manager_window.rs | 1 + src/ui/widgets/reception_led.rs | 1 + 13 files changed, 105 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 009fe97..3e2ead8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1357,6 +1357,19 @@ dependencies = [ "slab", ] +[[package]] +name = "generator" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1932,6 +1945,19 @@ version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + [[package]] name = "mach2" version = "0.4.2" @@ -2625,6 +2651,20 @@ name = "profiling" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", + "tracy-client", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn 2.0.98", +] [[package]] name = "quick-xml" @@ -2877,6 +2917,7 @@ dependencies = [ "egui_tiles", "enum_dispatch", "mavlink-bindgen", + "profiling", "ring-channel", "serde", "serde_json", @@ -2888,6 +2929,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", + "tracing-tracy", "uuid", ] @@ -3448,6 +3490,38 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tracing-tracy" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eaa1852afa96e0fe9e44caa53dc0bd2d9d05e0f2611ce09f97f8677af56e4ba" +dependencies = [ + "tracing-core", + "tracing-subscriber", + "tracy-client", +] + +[[package]] +name = "tracy-client" +version = "0.17.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73202d787346a5418f8222eddb5a00f29ea47caf3c7d38a8f2f69f8455fa7c7e" +dependencies = [ + "loom", + "once_cell", + "tracy-client-sys", +] + +[[package]] +name = "tracy-client-sys" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fff37da548239c3bf9e64a12193d261e8b22b660991c6fd2df057c168f435f" +dependencies = [ + "cc", + "windows-targets 0.52.6", +] + [[package]] name = "ttf-parser" version = "0.25.1" diff --git a/Cargo.toml b/Cargo.toml index 6f2eb0e..60bd536 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,11 +16,7 @@ egui_extras = "0.31" egui_plot = "0.31" egui_file = "0.22" # =========== Asynchronous =========== -tokio = { version = "1.41", features = [ - "rt-multi-thread", - "net", - "sync", -] } +tokio = { version = "1.41", features = ["rt-multi-thread", "net", "sync"] } # =========== Mavlink =========== skyward_mavlink = { git = "https://git.skywarder.eu/avn/swd/mavlink/mavlink-skyward-lib.git", branch = "rust-strum", features = [ "reflection", @@ -44,3 +40,5 @@ anyhow = "1.0" ring-channel = "0.12.0" thiserror = "2.0.7" uuid = { version = "1.12.1", features = ["serde", "v7"] } +profiling = { version = "1.0", features = ["profile-with-tracy"] } +tracing-tracy = "0.11.4" diff --git a/src/main.rs b/src/main.rs index e0c0555..1182687 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,15 +4,15 @@ mod error; mod mavlink; -mod serial; mod message_broker; +mod serial; mod ui; mod utils; use std::sync::LazyLock; use tokio::runtime::Runtime; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer}; +use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::SubscriberInitExt}; use error::ErrInstrument; use mavlink::ReflectionContext; @@ -28,6 +28,7 @@ fn main() -> Result<(), eframe::Error> { let env_filter = EnvFilter::builder().from_env_lossy(); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_filter(env_filter)) + .with(tracing_tracy::TracyLayer::default()) .init(); // Start Tokio runtime (TODO: decide whether to use Tokio or a simpler thread-based approach) diff --git a/src/mavlink/base.rs b/src/mavlink/base.rs index 0638719..c10d9fe 100644 --- a/src/mavlink/base.rs +++ b/src/mavlink/base.rs @@ -38,6 +38,7 @@ impl TimedMessage { } /// Extract fields from a MavLink message using string keys +#[profiling::function] pub fn extract_from_message<K, T>( message: &MavMessage, fields: impl IntoIterator<Item = K>, diff --git a/src/message_broker.rs b/src/message_broker.rs index dd3c7dc..77932cf 100644 --- a/src/message_broker.rs +++ b/src/message_broker.rs @@ -12,18 +12,18 @@ use reception_queue::ReceptionQueue; use crate::{ error::ErrInstrument, - mavlink::{byte_parser, Message, TimedMessage}, + mavlink::{Message, TimedMessage, byte_parser}, utils::RingBuffer, }; use anyhow::{Context, Result}; -use ring_channel::{ring_channel, RingReceiver, RingSender}; +use ring_channel::{RingReceiver, RingSender, ring_channel}; use std::{ collections::HashMap, io::Write, num::NonZeroUsize, sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, + atomic::{AtomicBool, Ordering}, }, time::{Duration, Instant}, }; diff --git a/src/ui/composable_view.rs b/src/ui/composable_view.rs index 4abda19..a97e1fd 100644 --- a/src/ui/composable_view.rs +++ b/src/ui/composable_view.rs @@ -82,6 +82,7 @@ impl eframe::App for ComposableView { match action { PaneAction::SplitH => { if let Some(hovered_tile) = hovered_pane { + profiling::scope!("split_h"); if self.maximized_pane.is_none() { debug!("Called SplitH on tile {:?}", hovered_tile); let hovered_tile_pane = panes_tree @@ -102,6 +103,7 @@ impl eframe::App for ComposableView { } } PaneAction::SplitV => { + profiling::scope!("split_v"); if self.maximized_pane.is_none() { if let Some(hovered_tile) = hovered_pane { debug!("Called SplitV on tile {:?}", hovered_tile); @@ -240,6 +242,9 @@ impl eframe::App for ComposableView { self.behavior.action = Some(action); } + // Used for the profiler + profiling::finish_frame!(); + // UNCOMMENT THIS TO ENABLE CONTINOUS MODE // ctx.request_repaint(); } @@ -285,6 +290,7 @@ impl ComposableView { } /// Retrieves new messages from the message broker and dispatches them to the panes. + #[profiling::function] fn process_messages(&mut self) { let start = Instant::now(); @@ -398,6 +404,7 @@ struct SourceWindow { } impl SourceWindow { + #[profiling::function] fn show_window(&mut self, ui: &mut egui::Ui, message_broker: &mut MessageBroker) { let mut window_is_open = self.visible; let mut can_be_closed = false; diff --git a/src/ui/panes/default.rs b/src/ui/panes/default.rs index 7fc0636..0507d4d 100644 --- a/src/ui/panes/default.rs +++ b/src/ui/panes/default.rs @@ -4,7 +4,7 @@ use tracing::debug; use crate::ui::{ composable_view::{PaneAction, PaneResponse}, - utils::{vertically_centered, SizingMemo}, + utils::{SizingMemo, vertically_centered}, }; #[derive(Clone, Debug, Default, Serialize, Deserialize)] @@ -22,6 +22,7 @@ impl PartialEq for DefaultPane { } impl PaneBehavior for DefaultPane { + #[profiling::function] fn ui(&mut self, ui: &mut egui::Ui, tile_id: egui_tiles::TileId) -> PaneResponse { let mut response = PaneResponse::default(); diff --git a/src/ui/panes/messages_viewer.rs b/src/ui/panes/messages_viewer.rs index 0925854..f1f63a9 100644 --- a/src/ui/panes/messages_viewer.rs +++ b/src/ui/panes/messages_viewer.rs @@ -18,6 +18,7 @@ impl PartialEq for MessagesViewerPane { } impl PaneBehavior for MessagesViewerPane { + #[profiling::function] fn ui(&mut self, ui: &mut egui::Ui, _tile_id: egui_tiles::TileId) -> PaneResponse { let mut response = PaneResponse::default(); let label = ui.add_sized(ui.available_size(), Label::new("This is a label")); diff --git a/src/ui/panes/plot.rs b/src/ui/panes/plot.rs index a7c4b5a..9433ed5 100644 --- a/src/ui/panes/plot.rs +++ b/src/ui/panes/plot.rs @@ -2,14 +2,14 @@ mod source_window; use super::PaneBehavior; use crate::{ - mavlink::{extract_from_message, MessageData, TimedMessage, ROCKET_FLIGHT_TM_DATA}, + mavlink::{MessageData, ROCKET_FLIGHT_TM_DATA, TimedMessage, extract_from_message}, ui::composable_view::PaneResponse, }; use egui::{Color32, Vec2b}; use egui_plot::{Legend, Line, PlotPoints}; use egui_tiles::TileId; use serde::{Deserialize, Serialize}; -use source_window::{sources_window, SourceSettings}; +use source_window::{SourceSettings, sources_window}; use std::iter::zip; #[derive(Clone, Default, Debug, Serialize, Deserialize)] @@ -37,6 +37,7 @@ impl PartialEq for Plot2DPane { } impl PaneBehavior for Plot2DPane { + #[profiling::function] fn ui(&mut self, ui: &mut egui::Ui, _: TileId) -> PaneResponse { let mut response = PaneResponse::default(); @@ -86,6 +87,7 @@ impl PaneBehavior for Plot2DPane { self.contains_pointer } + #[profiling::function] fn update(&mut self, messages: &[TimedMessage]) { if !self.state_valid { self.line_data.clear(); diff --git a/src/ui/panes/plot/source_window.rs b/src/ui/panes/plot/source_window.rs index d68fa93..f6def54 100644 --- a/src/ui/panes/plot/source_window.rs +++ b/src/ui/panes/plot/source_window.rs @@ -1,12 +1,13 @@ use crate::{ - mavlink::{MavMessage, Message}, MAVLINK_PROFILE, + mavlink::{MavMessage, Message}, }; use crate::error::ErrInstrument; use super::{LineSettings, MsgSources}; +#[profiling::function] pub fn sources_window(ui: &mut egui::Ui, plot_settings: &mut SourceSettings) { // extract the msg name from the id to show it in the combo box let msg_name = MAVLINK_PROFILE diff --git a/src/ui/persistency/layout_manager.rs b/src/ui/persistency/layout_manager.rs index 173fea1..c1a0eec 100644 --- a/src/ui/persistency/layout_manager.rs +++ b/src/ui/persistency/layout_manager.rs @@ -58,6 +58,7 @@ impl LayoutManager { } /// Scans the layout directory and reloads the layouts + #[profiling::function] pub fn reload_layouts(&mut self) { if let Ok(files) = self.layouts_path.read_dir() { trace!("Reloading layouts from {:?}", self.layouts_path); @@ -85,6 +86,7 @@ impl LayoutManager { self.layouts.get(&name.into()) } + #[profiling::function] pub fn save_layout(&mut self, name: &str, state: &ComposableViewState) -> anyhow::Result<()> { let path = self.layouts_path.join(name).with_extension("json"); state.to_file(&path)?; @@ -92,6 +94,7 @@ impl LayoutManager { Ok(()) } + #[profiling::function] pub fn load_layout( &mut self, path: impl AsRef<Path>, diff --git a/src/ui/persistency/layout_manager_window.rs b/src/ui/persistency/layout_manager_window.rs index b3cdbdc..0cd38bf 100644 --- a/src/ui/persistency/layout_manager_window.rs +++ b/src/ui/persistency/layout_manager_window.rs @@ -34,6 +34,7 @@ impl LayoutManagerWindow { } } + #[profiling::function] pub fn show( &mut self, ctx: &Context, diff --git a/src/ui/widgets/reception_led.rs b/src/ui/widgets/reception_led.rs index 5ff9e90..4c064ea 100644 --- a/src/ui/widgets/reception_led.rs +++ b/src/ui/widgets/reception_led.rs @@ -48,6 +48,7 @@ impl ReceptionLed { } impl Widget for ReceptionLed { + #[profiling::function] fn ui(self, ui: &mut Ui) -> Response { ui.horizontal(|ui| { ui.label("Receiving at:"); -- GitLab