From 7204374719f4021ce06c25e7dd72b09a56923954 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 09:44:21 +0200 Subject: Report instructions in addition to time They hopefully will be more stable on CI --- crates/ra_prof/Cargo.toml | 1 + crates/ra_prof/src/lib.rs | 2 ++ crates/ra_prof/src/stop_watch.rs | 72 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 crates/ra_prof/src/stop_watch.rs (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index 6c214501e..e41cb5f52 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -15,6 +15,7 @@ once_cell = "1.3.1" backtrace = { version = "0.3.44", optional = true } cfg-if = "0.1.10" libc = "0.2.73" +perf-event = "0.4" [features] cpu_profiler = [] diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index ba5609703..eb50965ae 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs @@ -1,5 +1,6 @@ //! A collection of tools for profiling rust-analyzer. +mod stop_watch; mod memory_usage; #[cfg(feature = "cpu_profiler")] mod google_cpu_profiler; @@ -11,6 +12,7 @@ use std::cell::RefCell; pub use crate::{ hprof::{init, init_from, profile}, memory_usage::{Bytes, MemoryUsage}, + stop_watch::{StopWatch, StopWatchSpan}, }; /// Prints backtrace to stderr, useful for debugging. diff --git a/crates/ra_prof/src/stop_watch.rs b/crates/ra_prof/src/stop_watch.rs new file mode 100644 index 000000000..54bfb0559 --- /dev/null +++ b/crates/ra_prof/src/stop_watch.rs @@ -0,0 +1,72 @@ +use crate::MemoryUsage; +use std::{ + fmt, + time::{Duration, Instant}, +}; + +pub struct StopWatch { + time: Instant, + counter: Option, + memory: Option, +} + +pub struct StopWatchSpan { + pub time: Duration, + pub instructions: Option, + pub memory: Option, +} + +impl StopWatch { + pub fn start() -> StopWatch { + let mut counter = perf_event::Builder::new().build().ok(); + if let Some(counter) = &mut counter { + let _ = counter.enable(); + } + let time = Instant::now(); + StopWatch { time, counter, memory: None } + } + pub fn memory(mut self, yes: bool) -> StopWatch { + if yes { + self.memory = Some(MemoryUsage::current()); + } + self + } + pub fn elapsed(&mut self) -> StopWatchSpan { + let time = self.time.elapsed(); + let instructions = self.counter.as_mut().and_then(|it| it.read().ok()); + let memory = self.memory.map(|it| MemoryUsage::current() - it); + StopWatchSpan { time, instructions, memory } + } +} + +impl fmt::Display for StopWatchSpan { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:.2?}", self.time)?; + if let Some(mut instructions) = self.instructions { + let mut prefix = ""; + if instructions > 10000 { + instructions /= 1000; + prefix = "k" + } + if instructions > 10000 { + instructions /= 1000; + prefix = "m" + } + write!(f, ", {}{}i", instructions, prefix)?; + } + if let Some(memory) = self.memory { + write!(f, ", {}", memory)?; + } + Ok(()) + } +} + +// Unclear if we need this: +// https://github.com/jimblandy/perf-event/issues/8 +impl Drop for StopWatch { + fn drop(&mut self) { + if let Some(mut counter) = self.counter.take() { + let _ = counter.disable(); + } + } +} -- cgit v1.2.3 From 5e498546e8275c86e0b3f711b069b2787c6385f2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 10:40:55 +0200 Subject: Fix non-linux compilation --- crates/ra_prof/Cargo.toml | 2 ++ crates/ra_prof/src/stop_watch.rs | 29 +++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index e41cb5f52..c82b9f76d 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -15,6 +15,8 @@ once_cell = "1.3.1" backtrace = { version = "0.3.44", optional = true } cfg-if = "0.1.10" libc = "0.2.73" + +[target.'cfg(target_os = "linux")'.dependencies] perf-event = "0.4" [features] diff --git a/crates/ra_prof/src/stop_watch.rs b/crates/ra_prof/src/stop_watch.rs index 54bfb0559..c52c92ce5 100644 --- a/crates/ra_prof/src/stop_watch.rs +++ b/crates/ra_prof/src/stop_watch.rs @@ -1,11 +1,13 @@ -use crate::MemoryUsage; use std::{ fmt, time::{Duration, Instant}, }; +use crate::MemoryUsage; + pub struct StopWatch { time: Instant, + #[cfg(target_os = "linux")] counter: Option, memory: Option, } @@ -18,12 +20,21 @@ pub struct StopWatchSpan { impl StopWatch { pub fn start() -> StopWatch { - let mut counter = perf_event::Builder::new().build().ok(); - if let Some(counter) = &mut counter { - let _ = counter.enable(); - } + #[cfg(target_os = "linux")] + let counter = { + let mut counter = perf_event::Builder::new().build().ok(); + if let Some(counter) = &mut counter { + let _ = counter.enable(); + } + counter + }; let time = Instant::now(); - StopWatch { time, counter, memory: None } + StopWatch { + time, + #[cfg(target_os = "linux")] + counter, + memory: None, + } } pub fn memory(mut self, yes: bool) -> StopWatch { if yes { @@ -33,7 +44,12 @@ impl StopWatch { } pub fn elapsed(&mut self) -> StopWatchSpan { let time = self.time.elapsed(); + + #[cfg(target_os = "linux")] let instructions = self.counter.as_mut().and_then(|it| it.read().ok()); + #[cfg(not(target_os = "linux"))] + let instructions = None; + let memory = self.memory.map(|it| MemoryUsage::current() - it); StopWatchSpan { time, instructions, memory } } @@ -65,6 +81,7 @@ impl fmt::Display for StopWatchSpan { // https://github.com/jimblandy/perf-event/issues/8 impl Drop for StopWatch { fn drop(&mut self) { + #[cfg(target_os = "linux")] if let Some(mut counter) = self.counter.take() { let _ = counter.disable(); } -- cgit v1.2.3 From f22af66c3763c4b2a9d16621473cb6979fb2f36d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 10:43:47 +0200 Subject: Fixes --- crates/ra_prof/src/stop_watch.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/src/stop_watch.rs b/crates/ra_prof/src/stop_watch.rs index c52c92ce5..8b8ec25a5 100644 --- a/crates/ra_prof/src/stop_watch.rs +++ b/crates/ra_prof/src/stop_watch.rs @@ -1,3 +1,4 @@ +//! Like `std::time::Instant`, but also measures memory & CPU cycles. use std::{ fmt, time::{Duration, Instant}, @@ -76,14 +77,3 @@ impl fmt::Display for StopWatchSpan { Ok(()) } } - -// Unclear if we need this: -// https://github.com/jimblandy/perf-event/issues/8 -impl Drop for StopWatch { - fn drop(&mut self) { - #[cfg(target_os = "linux")] - if let Some(mut counter) = self.counter.take() { - let _ = counter.disable(); - } - } -} -- cgit v1.2.3