From 0ce0cab2448d61de1d6c404ad087e1d2e4812a35 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Thu, 20 Nov 2025 18:50:30 +0100 Subject: [PATCH 1/5] feat: add memory profiling in CI --- .github/workflows/ci.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ec0b066..e0ba61e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,6 +194,43 @@ jobs: mode: walltime token: ${{ secrets.CODSPEED_TOKEN }} + + compat-integration-test-memory: + runs-on: ubuntu-latest + strategy: + matrix: + package: + - codspeed-divan-compat + - codspeed-divan-compat-examples + - codspeed-criterion-compat + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: moonrepo/setup-rust@v1 + with: + cache-target: release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - run: cargo install --path crates/cargo-codspeed --locked + + - run: | + # Remove the cargo config else it forces instrumentation mode + rm -f .cargo/config.toml + cargo codspeed build -p ${{ matrix.package }} -m instrumentation + + # TODO: Enable once we can upload it + # - name: Run the benchmarks + # uses: CodSpeedHQ/action@chore/runner-branch + # env: + # MY_ENV_VAR: "YES" + # with: + # runner-branch: cod-1670-runner-profile-memory-of-command + # run: cargo codspeed run + # mode: memory + # token: ${{ secrets.CODSPEED_TOKEN }} + musl-build-check: strategy: matrix: From 5a5d4505f742507a7355064b387a240ca46dd2c3 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Wed, 19 Nov 2025 19:31:47 +0100 Subject: [PATCH 2/5] feat: add support for analysis mode --- crates/codspeed/src/codspeed.rs | 9 +++++++-- crates/codspeed/src/measurement.rs | 11 ----------- crates/codspeed/src/request/mod.rs | 1 - 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/crates/codspeed/src/codspeed.rs b/crates/codspeed/src/codspeed.rs index 937036be..0fb5a3ec 100644 --- a/crates/codspeed/src/codspeed.rs +++ b/crates/codspeed/src/codspeed.rs @@ -1,4 +1,4 @@ -use crate::measurement; +use crate::{instrument_hooks::InstrumentHooks, measurement}; use colored::Colorize; use std::ffi::CString; @@ -19,7 +19,8 @@ pub struct CodSpeed { impl CodSpeed { pub fn new() -> Self { - let is_instrumented = measurement::is_instrumented(); + let ih = InstrumentHooks::instance(); + let is_instrumented = ih.is_instrumented(); if !is_instrumented { println!( "{} codspeed is enabled, but no performance measurement will be made since it's running in an unknown environment.", @@ -46,12 +47,16 @@ impl CodSpeed { #[inline(always)] pub fn start_benchmark(&mut self, name: &str) { self.current_benchmark = CString::new(name).expect("CString::new failed"); + let _ = InstrumentHooks::instance().start_benchmark(); measurement::start(); } #[inline(always)] pub fn end_benchmark(&mut self) { measurement::stop(&self.current_benchmark); + let _ = InstrumentHooks::instance().stop_benchmark(); + let _ = InstrumentHooks::instance() + .set_executed_benchmark(&self.current_benchmark.to_string_lossy()); self.benchmarked .push(self.current_benchmark.to_str().unwrap().to_string()); let action_str = if self.is_instrumented { diff --git a/crates/codspeed/src/measurement.rs b/crates/codspeed/src/measurement.rs index 9780e667..1169789f 100644 --- a/crates/codspeed/src/measurement.rs +++ b/crates/codspeed/src/measurement.rs @@ -2,17 +2,6 @@ use std::ffi::CString; use crate::request::{send_client_request, ClientRequest, Value}; -#[inline(always)] -pub fn is_instrumented() -> bool { - let valgrind_depth = unsafe { - send_client_request( - 0, - &[ClientRequest::RunningOnValgrind as Value, 0, 0, 0, 0, 0], - ) - }; - valgrind_depth > 0 -} - #[inline(always)] pub fn set_metadata() { let full_metadata = CString::new(format!( diff --git a/crates/codspeed/src/request/mod.rs b/crates/codspeed/src/request/mod.rs index a59fd322..6377cb94 100644 --- a/crates/codspeed/src/request/mod.rs +++ b/crates/codspeed/src/request/mod.rs @@ -3,7 +3,6 @@ const CG_BASE: u32 = ((b'C' as u32) << 24) + ((b'T' as u32) << 16); #[allow(non_camel_case_types)] #[repr(u32)] pub enum ClientRequest { - RunningOnValgrind = 0x1001, ZeroStatistics = CG_BASE + 1, DumpStatisticsAt = CG_BASE + 3, StartInstrumentation = CG_BASE + 4, From 00751f6523b69d5631c0b26fae7688b6a45c736b Mon Sep 17 00:00:00 2001 From: not-matthias Date: Thu, 20 Nov 2025 18:47:37 +0100 Subject: [PATCH 3/5] chore: add example with allocations --- crates/divan_compat/examples/Cargo.toml | 4 ++ crates/divan_compat/examples/benches/alloc.rs | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 crates/divan_compat/examples/benches/alloc.rs diff --git a/crates/divan_compat/examples/Cargo.toml b/crates/divan_compat/examples/Cargo.toml index 1e9ea793..40c57f3c 100644 --- a/crates/divan_compat/examples/Cargo.toml +++ b/crates/divan_compat/examples/Cargo.toml @@ -44,3 +44,7 @@ harness = false [[bench]] name = "counters" harness = false + +[[bench]] +name = "alloc" +harness = false diff --git a/crates/divan_compat/examples/benches/alloc.rs b/crates/divan_compat/examples/benches/alloc.rs new file mode 100644 index 00000000..d7d69d04 --- /dev/null +++ b/crates/divan_compat/examples/benches/alloc.rs @@ -0,0 +1,38 @@ +use std::{ + alloc::Layout, + collections::{HashMap, HashSet}, +}; + +#[divan::bench] +fn allocate() { + println!("Hello, world!"); + + let vec = vec![1, 2, 3]; + println!("{vec:?}"); + + let mut map = HashMap::new(); + map.insert("key", "value"); + println!("{map:?}"); + + let mut set = HashSet::new(); + set.insert("apple"); + set.insert("banana"); + println!("{set:?}"); + + std::thread::sleep(std::time::Duration::from_secs(1)); + + let mut bytes_vec = vec![0u8; 0x100]; + println!("{:?}", bytes_vec.len()); + + bytes_vec.extend(&vec![0u8; 0x1000]); + + // Alloc 256 bytes of memory + for _ in 0..100 { + let memory = unsafe { std::alloc::alloc(Layout::new::<[u8; 42]>()) }; + core::hint::black_box(memory); + } +} + +fn main() { + divan::main(); +} From db928b2d401f4f6ef51319a43b006e7ca34b54c7 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Fri, 21 Nov 2025 16:22:12 +0100 Subject: [PATCH 4/5] feat(cargo-codspeed): add analysis build mode --- crates/cargo-codspeed/src/build.rs | 4 +++- crates/cargo-codspeed/src/measurement_mode.rs | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/cargo-codspeed/src/build.rs b/crates/cargo-codspeed/src/build.rs index 4cc28b83..6cea76f9 100644 --- a/crates/cargo-codspeed/src/build.rs +++ b/crates/cargo-codspeed/src/build.rs @@ -226,7 +226,9 @@ See `cargo codspeed build --help` for more information."); ]; // Add the codspeed cfg flag if simulation mode is enabled - if measurement_mode == MeasurementMode::Simulation { + if measurement_mode == MeasurementMode::Simulation + || measurement_mode == MeasurementMode::Analysis + { flags.push("--cfg=codspeed".to_owned()); } diff --git a/crates/cargo-codspeed/src/measurement_mode.rs b/crates/cargo-codspeed/src/measurement_mode.rs index 171ac611..97c3f716 100644 --- a/crates/cargo-codspeed/src/measurement_mode.rs +++ b/crates/cargo-codspeed/src/measurement_mode.rs @@ -9,6 +9,7 @@ pub enum MeasurementMode { #[value(alias = "instrumentation")] Simulation, Walltime, + Analysis, } impl fmt::Display for MeasurementMode { @@ -19,6 +20,7 @@ impl fmt::Display for MeasurementMode { match self { MeasurementMode::Simulation => "simulation", MeasurementMode::Walltime => "walltime", + MeasurementMode::Analysis => "analysis", } ) } From f2e74d765a1d14dc20fd114b52f56ad7e6607a60 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Fri, 21 Nov 2025 16:24:43 +0100 Subject: [PATCH 5/5] chore: bump instrument-hooks --- crates/codspeed/instrument-hooks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/codspeed/instrument-hooks b/crates/codspeed/instrument-hooks index 1752e9e4..c4f95c0f 160000 --- a/crates/codspeed/instrument-hooks +++ b/crates/codspeed/instrument-hooks @@ -1 +1 @@ -Subproject commit 1752e9e4eae585e26703932d0055a1473dd77048 +Subproject commit c4f95c0ff879e13fa65fcdea0d6cfe89fb2ccf3b