From e7ba7f47a79a2881cf208ef9d944609e8fd4eec9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 11 Jul 2020 03:04:37 +0200 Subject: Profiling tweaks --- crates/ra_prof/Cargo.toml | 5 +++++ crates/ra_prof/src/lib.rs | 2 ++ 2 files changed, 7 insertions(+) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index c33b5121a..eabfcebb0 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -20,3 +20,8 @@ jemalloc-ctl = { version = "0.3.3", optional = true } [features] jemalloc = [ "jemallocator", "jemalloc-ctl" ] cpu_profiler = [] + +# Uncomment to enable for the whole crate graph +# default = [ "backtrace" ] +# default = [ "jemalloc" ] +# default = [ "cpu_profiler" ] diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index 89df7f04b..0fb468375 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs @@ -43,6 +43,7 @@ pub struct Scope { } impl Scope { + #[must_use] pub fn enter() -> Scope { let prev = IN_SCOPE.with(|slot| std::mem::replace(&mut *slot.borrow_mut(), true)); Scope { prev } @@ -78,6 +79,7 @@ pub struct CpuProfiler { _private: (), } +#[must_use] pub fn cpu_profiler() -> CpuProfiler { #[cfg(feature = "cpu_profiler")] { -- cgit v1.2.3 From 5e25000763e97ef006dd05ac40198ae59e3f03c3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 11 Jul 2020 03:39:44 +0200 Subject: Profiling example --- crates/ra_prof/Cargo.toml | 2 +- crates/ra_prof/src/lib.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index eabfcebb0..db9b59ed6 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -24,4 +24,4 @@ cpu_profiler = [] # Uncomment to enable for the whole crate graph # default = [ "backtrace" ] # default = [ "jemalloc" ] -# default = [ "cpu_profiler" ] +default = [ "cpu_profiler" ] diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index 0fb468375..7163a8424 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs @@ -66,7 +66,8 @@ impl Drop for Scope { /// 2. Build with `cpu_profiler` feature. /// 3. Tun the code, the *raw* output would be in the `./out.profile` file. /// 4. Install pprof for visualization (https://github.com/google/pprof). -/// 5. Use something like `pprof -svg target/release/rust-analyzer ./out.profile` to see the results. +/// 5. Bump sampling frequency to once per ms: `export CPUPROFILE_FREQUENCY=1000` +/// 6. Use something like `pprof -svg target/release/rust-analyzer ./out.profile` to see the results. /// /// For example, here's how I run profiling on NixOS: /// @@ -74,6 +75,10 @@ impl Drop for Scope { /// $ nix-shell -p gperftools --run \ /// 'cargo run --release -p rust-analyzer -- parse < ~/projects/rustbench/parser.rs > /dev/null' /// ``` +/// +/// See this diff for how to profile completions: +/// +/// https://github.com/rust-analyzer/rust-analyzer/pull/5306 #[derive(Debug)] pub struct CpuProfiler { _private: (), -- cgit v1.2.3 From 7f6e5de37c3c5a73865350cab1c976291be56fe2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 11 Jul 2020 03:41:52 +0200 Subject: disable profiling --- crates/ra_prof/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index db9b59ed6..eabfcebb0 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -24,4 +24,4 @@ cpu_profiler = [] # Uncomment to enable for the whole crate graph # default = [ "backtrace" ] # default = [ "jemalloc" ] -default = [ "cpu_profiler" ] +# default = [ "cpu_profiler" ] -- cgit v1.2.3 From 6f423466d181130848c229e2684c6dd18f8a5e9d Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 14 Jul 2020 10:57:26 +0900 Subject: Add a license field to all the crates --- crates/ra_prof/Cargo.toml | 1 + 1 file changed, 1 insertion(+) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index eabfcebb0..69ac51c9e 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -4,6 +4,7 @@ name = "ra_prof" version = "0.1.0" authors = ["rust-analyzer developers"] publish = false +license = "MIT OR Apache-2.0" [lib] doctest = false -- cgit v1.2.3 From 6710856c1098f71168c47451af53bac9a33b49dd Mon Sep 17 00:00:00 2001 From: Ivan Kozik Date: Tue, 14 Jul 2020 00:12:49 +0000 Subject: Add opt-in mimalloc feature --- crates/ra_prof/Cargo.toml | 2 ++ crates/ra_prof/src/lib.rs | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index eabfcebb0..3cd8481ea 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -12,6 +12,7 @@ doctest = false ra_arena = { path = "../ra_arena" } once_cell = "1.3.1" backtrace = { version = "0.3.44", optional = true } +mimalloc = { version = "0.1.19", default-features = false, optional = true } [target.'cfg(not(target_env = "msvc"))'.dependencies] jemallocator = { version = "0.3.2", optional = true } @@ -24,4 +25,5 @@ cpu_profiler = [] # Uncomment to enable for the whole crate graph # default = [ "backtrace" ] # default = [ "jemalloc" ] +# default = [ "mimalloc" ] # default = [ "cpu_profiler" ] diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index 7163a8424..b54531b4e 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs @@ -19,6 +19,10 @@ pub use crate::{ #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; +#[cfg(all(feature = "mimalloc"))] +#[global_allocator] +static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; + /// Prints backtrace to stderr, useful for debugging. #[cfg(feature = "backtrace")] pub fn print_backtrace() { -- cgit v1.2.3 From 56c090d0d0ad68c0dd195684e4d8180ea149692f Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 21 Jul 2020 19:30:17 +0200 Subject: Allow gathering memory stats on non-jemalloc Linux --- crates/ra_prof/Cargo.toml | 2 ++ crates/ra_prof/src/memory_usage.rs | 25 +++++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index b3d52985a..2e60858f1 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -14,6 +14,8 @@ ra_arena = { path = "../ra_arena" } once_cell = "1.3.1" backtrace = { version = "0.3.44", optional = true } mimalloc = { version = "0.1.19", default-features = false, optional = true } +cfg-if = "0.1.10" +libc = "0.2.73" [target.'cfg(not(target_env = "msvc"))'.dependencies] jemallocator = { version = "0.3.2", optional = true } diff --git a/crates/ra_prof/src/memory_usage.rs b/crates/ra_prof/src/memory_usage.rs index 9768f656c..b1858b06f 100644 --- a/crates/ra_prof/src/memory_usage.rs +++ b/crates/ra_prof/src/memory_usage.rs @@ -1,5 +1,6 @@ //! FIXME: write short doc here +use cfg_if::cfg_if; use std::fmt; pub struct MemoryUsage { @@ -8,19 +9,23 @@ pub struct MemoryUsage { } impl MemoryUsage { - #[cfg(all(feature = "jemalloc", not(target_env = "msvc")))] pub fn current() -> MemoryUsage { - jemalloc_ctl::epoch::advance().unwrap(); - MemoryUsage { - allocated: Bytes(jemalloc_ctl::stats::allocated::read().unwrap()), - resident: Bytes(jemalloc_ctl::stats::resident::read().unwrap()), + cfg_if! { + if #[cfg(all(feature = "jemalloc", not(target_env = "msvc")))] { + jemalloc_ctl::epoch::advance().unwrap(); + MemoryUsage { + allocated: Bytes(jemalloc_ctl::stats::allocated::read().unwrap()), + resident: Bytes(jemalloc_ctl::stats::resident::read().unwrap()), + } + } else if #[cfg(target_os = "linux")] { + // Note: This is incredibly slow. + let alloc = unsafe { libc::mallinfo() }.uordblks as u32 as usize; + MemoryUsage { allocated: Bytes(alloc), resident: Bytes(0) } + } else { + MemoryUsage { allocated: Bytes(0), resident: Bytes(0) } + } } } - - #[cfg(any(not(feature = "jemalloc"), target_env = "msvc"))] - pub fn current() -> MemoryUsage { - MemoryUsage { allocated: Bytes(0), resident: Bytes(0) } - } } impl fmt::Display for MemoryUsage { -- cgit v1.2.3 From deed44a472edaf11d35fa98c7e68a288f8dfe93f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 22 Jul 2020 13:40:45 +0200 Subject: Remove support for jemalloc We only used it for measuring memory usage, but now we can use glibc's allocator for that just fine --- crates/ra_prof/Cargo.toml | 6 ------ crates/ra_prof/src/lib.rs | 6 ------ crates/ra_prof/src/memory_usage.rs | 10 ++-------- 3 files changed, 2 insertions(+), 20 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index 2e60858f1..84d895317 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -17,16 +17,10 @@ mimalloc = { version = "0.1.19", default-features = false, optional = true } cfg-if = "0.1.10" libc = "0.2.73" -[target.'cfg(not(target_env = "msvc"))'.dependencies] -jemallocator = { version = "0.3.2", optional = true } -jemalloc-ctl = { version = "0.3.3", optional = true } - [features] -jemalloc = [ "jemallocator", "jemalloc-ctl" ] cpu_profiler = [] # Uncomment to enable for the whole crate graph # default = [ "backtrace" ] -# default = [ "jemalloc" ] # default = [ "mimalloc" ] # default = [ "cpu_profiler" ] diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index b54531b4e..a5b408a1d 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs @@ -13,12 +13,6 @@ pub use crate::{ memory_usage::{Bytes, MemoryUsage}, }; -// We use jemalloc mainly to get heap usage statistics, actual performance -// difference is not measures. -#[cfg(all(feature = "jemalloc", not(target_env = "msvc")))] -#[global_allocator] -static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; - #[cfg(all(feature = "mimalloc"))] #[global_allocator] static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; diff --git a/crates/ra_prof/src/memory_usage.rs b/crates/ra_prof/src/memory_usage.rs index b1858b06f..ee79ec3ee 100644 --- a/crates/ra_prof/src/memory_usage.rs +++ b/crates/ra_prof/src/memory_usage.rs @@ -1,7 +1,7 @@ //! FIXME: write short doc here +use std::fmt; use cfg_if::cfg_if; -use std::fmt; pub struct MemoryUsage { pub allocated: Bytes, @@ -11,13 +11,7 @@ pub struct MemoryUsage { impl MemoryUsage { pub fn current() -> MemoryUsage { cfg_if! { - if #[cfg(all(feature = "jemalloc", not(target_env = "msvc")))] { - jemalloc_ctl::epoch::advance().unwrap(); - MemoryUsage { - allocated: Bytes(jemalloc_ctl::stats::allocated::read().unwrap()), - resident: Bytes(jemalloc_ctl::stats::resident::read().unwrap()), - } - } else if #[cfg(target_os = "linux")] { + if #[cfg(target_os = "linux")] { // Note: This is incredibly slow. let alloc = unsafe { libc::mallinfo() }.uordblks as u32 as usize; MemoryUsage { allocated: Bytes(alloc), resident: Bytes(0) } -- cgit v1.2.3 From 9ad41eb9085cd7ceaf479f659a7071df81059b7c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 22 Jul 2020 13:42:53 +0200 Subject: Setup global allocator in the correct crate It worked before, but was roundabout --- crates/ra_prof/Cargo.toml | 2 -- crates/ra_prof/src/lib.rs | 4 ---- 2 files changed, 6 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index 84d895317..6c214501e 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml @@ -13,7 +13,6 @@ doctest = false ra_arena = { path = "../ra_arena" } once_cell = "1.3.1" backtrace = { version = "0.3.44", optional = true } -mimalloc = { version = "0.1.19", default-features = false, optional = true } cfg-if = "0.1.10" libc = "0.2.73" @@ -22,5 +21,4 @@ cpu_profiler = [] # Uncomment to enable for the whole crate graph # default = [ "backtrace" ] -# default = [ "mimalloc" ] # default = [ "cpu_profiler" ] diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index a5b408a1d..ba5609703 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs @@ -13,10 +13,6 @@ pub use crate::{ memory_usage::{Bytes, MemoryUsage}, }; -#[cfg(all(feature = "mimalloc"))] -#[global_allocator] -static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; - /// Prints backtrace to stderr, useful for debugging. #[cfg(feature = "backtrace")] pub fn print_backtrace() { -- cgit v1.2.3 From 451edcc09866d43def7db88d5d9c139a96ead58e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 25 Jul 2020 10:35:45 +0200 Subject: Add rustc-perf to metrics --- crates/ra_prof/src/memory_usage.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/src/memory_usage.rs b/crates/ra_prof/src/memory_usage.rs index ee79ec3ee..745345fac 100644 --- a/crates/ra_prof/src/memory_usage.rs +++ b/crates/ra_prof/src/memory_usage.rs @@ -31,6 +31,12 @@ impl fmt::Display for MemoryUsage { #[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] pub struct Bytes(usize); +impl Bytes { + pub fn megabytes(self) -> usize { + self.0 / 1024 / 1024 + } +} + impl fmt::Display for Bytes { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let bytes = self.0; -- cgit v1.2.3 From dae99b66611759ba48fd164646f077d3e8515dad Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 09:45:20 +0200 Subject: Drop resident from memory usage --- crates/ra_prof/src/memory_usage.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/src/memory_usage.rs b/crates/ra_prof/src/memory_usage.rs index 745345fac..857b51321 100644 --- a/crates/ra_prof/src/memory_usage.rs +++ b/crates/ra_prof/src/memory_usage.rs @@ -5,7 +5,6 @@ use cfg_if::cfg_if; pub struct MemoryUsage { pub allocated: Bytes, - pub resident: Bytes, } impl MemoryUsage { @@ -14,9 +13,9 @@ impl MemoryUsage { if #[cfg(target_os = "linux")] { // Note: This is incredibly slow. let alloc = unsafe { libc::mallinfo() }.uordblks as u32 as usize; - MemoryUsage { allocated: Bytes(alloc), resident: Bytes(0) } + MemoryUsage { allocated: Bytes(alloc) } } else { - MemoryUsage { allocated: Bytes(0), resident: Bytes(0) } + MemoryUsage { allocated: Bytes(0) } } } } @@ -24,7 +23,7 @@ impl MemoryUsage { impl fmt::Display for MemoryUsage { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{} allocated {} resident", self.allocated, self.resident,) + write!(fmt, "{}", self.allocated) } } -- cgit v1.2.3 From afab67e69c39027fb99878751309d4050324beef Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 09:47:16 +0200 Subject: Allow negative bytes Gotta be optimistic about those memory usage optimizations --- crates/ra_prof/src/memory_usage.rs | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/src/memory_usage.rs b/crates/ra_prof/src/memory_usage.rs index 857b51321..22b61e4a2 100644 --- a/crates/ra_prof/src/memory_usage.rs +++ b/crates/ra_prof/src/memory_usage.rs @@ -3,16 +3,30 @@ use std::fmt; use cfg_if::cfg_if; +#[derive(Copy, Clone)] pub struct MemoryUsage { pub allocated: Bytes, } +impl fmt::Display for MemoryUsage { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{}", self.allocated) + } +} + +impl std::ops::Sub for MemoryUsage { + type Output = MemoryUsage; + fn sub(self, rhs: MemoryUsage) -> MemoryUsage { + MemoryUsage { allocated: self.allocated - rhs.allocated } + } +} + impl MemoryUsage { pub fn current() -> MemoryUsage { cfg_if! { if #[cfg(target_os = "linux")] { // Note: This is incredibly slow. - let alloc = unsafe { libc::mallinfo() }.uordblks as u32 as usize; + let alloc = unsafe { libc::mallinfo() }.uordblks as u32 as isize; MemoryUsage { allocated: Bytes(alloc) } } else { MemoryUsage { allocated: Bytes(0) } @@ -21,17 +35,11 @@ impl MemoryUsage { } } -impl fmt::Display for MemoryUsage { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}", self.allocated) - } -} - #[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] -pub struct Bytes(usize); +pub struct Bytes(isize); impl Bytes { - pub fn megabytes(self) -> usize { + pub fn megabytes(self) -> isize { self.0 / 1024 / 1024 } } @@ -41,10 +49,10 @@ impl fmt::Display for Bytes { let bytes = self.0; let mut value = bytes; let mut suffix = "b"; - if value > 4096 { + if value.abs() > 4096 { value /= 1024; suffix = "kb"; - if value > 4096 { + if value.abs() > 4096 { value /= 1024; suffix = "mb"; } @@ -55,7 +63,7 @@ impl fmt::Display for Bytes { impl std::ops::AddAssign for Bytes { fn add_assign(&mut self, x: usize) { - self.0 += x; + self.0 += x as isize; } } -- cgit v1.2.3 From 4bab553029da31f3e90e99d8b83d160a34fdf4b2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 10:14:35 +0200 Subject: fix cast --- crates/ra_prof/src/memory_usage.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/src/memory_usage.rs b/crates/ra_prof/src/memory_usage.rs index 22b61e4a2..c2ecbd33c 100644 --- a/crates/ra_prof/src/memory_usage.rs +++ b/crates/ra_prof/src/memory_usage.rs @@ -26,7 +26,7 @@ impl MemoryUsage { cfg_if! { if #[cfg(target_os = "linux")] { // Note: This is incredibly slow. - let alloc = unsafe { libc::mallinfo() }.uordblks as u32 as isize; + let alloc = unsafe { libc::mallinfo() }.uordblks as isize; MemoryUsage { allocated: Bytes(alloc) } } else { MemoryUsage { allocated: Bytes(0) } -- cgit v1.2.3 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 From 3e1e6227ca525f8631e0bff2215fa3de1b4f4cc1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 14:27:19 +0200 Subject: Print errors when failing to create a perf counter --- crates/ra_prof/src/stop_watch.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 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 8b8ec25a5..5e276190e 100644 --- a/crates/ra_prof/src/stop_watch.rs +++ b/crates/ra_prof/src/stop_watch.rs @@ -23,9 +23,14 @@ impl StopWatch { pub fn start() -> StopWatch { #[cfg(target_os = "linux")] let counter = { - let mut counter = perf_event::Builder::new().build().ok(); + let mut counter = perf_event::Builder::new() + .build() + .map_err(|err| eprintln!("Failed to create perf counter: {}", err)) + .ok(); if let Some(counter) = &mut counter { - let _ = counter.enable(); + if let Err(err) = counter.enable() { + eprintln!("Failed to start perf counter: {}", err) + } } counter }; @@ -47,7 +52,9 @@ impl StopWatch { let time = self.time.elapsed(); #[cfg(target_os = "linux")] - let instructions = self.counter.as_mut().and_then(|it| it.read().ok()); + let instructions = self.counter.as_mut().and_then(|it| { + it.read().map_err(|err| eprintln!("Failed to read perf counter: {}", err)).ok() + }); #[cfg(not(target_os = "linux"))] let instructions = None; -- cgit v1.2.3