Skip to content

Commit 1545735

Browse files
committed
feat(divan): run multiple rounds of analysis mode
1 parent 7fc87c3 commit 1545735

File tree

4 files changed

+69
-11
lines changed

4 files changed

+69
-11
lines changed

crates/codspeed/src/instrument_hooks/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ mod ffi;
33

44
#[cfg(use_instrument_hooks)]
55
mod linux_impl {
6-
76
use super::ffi;
7+
use crate::measurement;
88
use std::ffi::CString;
99
use std::sync::OnceLock;
1010

@@ -44,6 +44,12 @@ mod linux_impl {
4444
unsafe { ffi::instrument_hooks_is_instrumented(self.0) }
4545
}
4646

47+
// FIXME: Should we move this to instrument-hooks native library?
48+
#[inline(always)]
49+
pub fn toggle_collect() {
50+
measurement::toggle_collect();
51+
}
52+
4753
#[inline(always)]
4854
pub fn start_benchmark(&self) -> Result<(), u8> {
4955
let result = unsafe { ffi::instrument_hooks_start_benchmark(self.0) };
@@ -165,6 +171,9 @@ mod other_impl {
165171
false
166172
}
167173

174+
#[inline(always)]
175+
pub fn toggle_collect() {}
176+
168177
pub fn start_benchmark(&self) -> Result<(), u8> {
169178
Ok(())
170179
}

crates/codspeed/src/measurement.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ pub fn set_metadata() {
3535
}
3636
}
3737

38+
#[inline(always)]
39+
pub fn toggle_collect() {
40+
unsafe { send_client_request(0, &[ClientRequest::ToggleCollect as Value, 0, 0, 0, 0, 0]) };
41+
}
42+
3843
#[inline(always)]
3944
pub fn start() {
4045
unsafe {

crates/codspeed/src/request/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const CG_BASE: u32 = ((b'C' as u32) << 24) + ((b'T' as u32) << 16);
55
pub enum ClientRequest {
66
RunningOnValgrind = 0x1001,
77
ZeroStatistics = CG_BASE + 1,
8+
ToggleCollect = CG_BASE + 2,
89
DumpStatisticsAt = CG_BASE + 3,
910
StartInstrumentation = CG_BASE + 4,
1011
StopInstrumentation = CG_BASE + 5,

crates/divan_compat/src/compat/bench/mod.rs

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ pub use self::{
1010
options::BenchOptions,
1111
};
1212

13-
use codspeed::codspeed::CodSpeed;
13+
use ::codspeed::codspeed::CodSpeed;
14+
use ::codspeed::instrument_hooks::InstrumentHooks;
1415
use std::cell::RefCell;
1516

1617
/// Using this in place of `()` for `GenI` prevents `Bencher::with_inputs` from
@@ -136,11 +137,15 @@ where
136137
{
137138
let mut codspeed = self.codspeed.borrow_mut();
138139
let mut gen_input = self.config.gen_input.borrow_mut();
139-
let input = gen_input();
140-
codspeed.start_benchmark(self.uri.as_str());
141-
let output = benched(input);
142-
codspeed.end_benchmark();
143-
divan::black_box(output);
140+
141+
codspeed::run_rounds(&mut codspeed, self.uri.as_str(), || {
142+
// FIXME: We could also run multiple rounds here
143+
let input = gen_input();
144+
InstrumentHooks::toggle_collect();
145+
let output = benched(divan::black_box(input));
146+
InstrumentHooks::toggle_collect();
147+
divan::black_box(output);
148+
});
144149
}
145150

146151
pub fn bench_local_refs<O, B>(self, mut benched: B)
@@ -149,11 +154,49 @@ where
149154
{
150155
let mut codspeed = self.codspeed.borrow_mut();
151156
let mut gen_input = self.config.gen_input.borrow_mut();
152-
let mut input = gen_input();
153157

154-
codspeed.start_benchmark(self.uri.as_str());
155-
let output = benched(&mut input);
158+
codspeed::run_rounds(&mut codspeed, self.uri.as_str(), || {
159+
let mut input = gen_input();
160+
InstrumentHooks::toggle_collect();
161+
let output = benched(&mut input);
162+
InstrumentHooks::toggle_collect();
163+
divan::black_box(input);
164+
divan::black_box(output);
165+
});
166+
}
167+
}
168+
169+
mod codspeed {
170+
use super::*;
171+
use std::time::{Duration, Instant};
172+
173+
pub fn run_rounds(codspeed: &mut CodSpeed, uri: &str, mut run_iteration: impl FnMut()) {
174+
// FIXME: Maybe move this to codspeed
175+
let (max_rounds, max_duration) = match std::env::var("CODSPEED_RUNNER_MODE").as_deref() {
176+
Ok("simulation") | Ok("instrumentation") => (None, Some(Duration::from_millis(100))),
177+
Ok("memory") => (Some(1), None),
178+
Ok(m) => unreachable!("Invalid runner mode: {m}"),
179+
Err(err) => panic!("Failed to get runner mode: {err}"),
180+
};
181+
let mut rounds = 0;
182+
let rounds_start_time = Instant::now();
183+
184+
codspeed.start_benchmark(uri);
185+
InstrumentHooks::toggle_collect(); // Pause collection
186+
187+
loop {
188+
rounds += 1;
189+
190+
run_iteration();
191+
192+
let within_rounds = max_rounds.map_or(true, |max| rounds < max);
193+
let within_duration =
194+
max_duration.map_or(true, |max| rounds_start_time.elapsed() < max);
195+
if !(within_rounds && within_duration) {
196+
break;
197+
}
198+
}
199+
156200
codspeed.end_benchmark();
157-
divan::black_box(output);
158201
}
159202
}

0 commit comments

Comments
 (0)