harness_probe_perf/
lib.rs

1#[cfg(target_os = "linux")]
2use std::collections::HashMap;
3
4use harness::probe::Probe;
5#[cfg(target_os = "linux")]
6use harness::probe::ProbeArgs;
7#[cfg(target_os = "linux")]
8use harness::Value;
9
10#[harness::probe]
11#[derive(Default)]
12pub struct PerfEventProbe {
13    #[cfg(target_os = "linux")]
14    perfmon: pfm::Perfmon,
15    #[cfg(target_os = "linux")]
16    events: Vec<pfm::PerfEvent>,
17    #[cfg(target_os = "linux")]
18    event_names: Vec<String>,
19}
20
21#[cfg(not(target_os = "linux"))]
22impl Probe for PerfEventProbe {}
23
24#[cfg(target_os = "linux")]
25impl Probe for PerfEventProbe {
26    /// Initialize the probe before benchmarking.
27    fn init(&mut self, args: ProbeArgs) {
28        self.perfmon.initialize().expect("libpfm init failed.");
29        let events = args.get::<String>("events").unwrap_or_default();
30        let inherit = args.get::<bool>("inherit").unwrap_or_default();
31        self.event_names = events
32            .split(',')
33            .map(|s| s.trim())
34            .filter(|s| !s.is_empty())
35            .map(|s| s.to_owned())
36            .collect();
37        self.events = self
38            .event_names
39            .iter()
40            .map(|s| pfm::PerfEvent::new(s, inherit).unwrap())
41            .collect();
42        for e in &mut self.events {
43            e.open(0, -1).unwrap();
44        }
45    }
46
47    /// Prepare recording at the start of the timing iteration.
48    fn begin(&mut self, _benchmark: &str, _iteration: usize, _warmup: bool) {
49        for e in &mut self.events {
50            e.reset().expect("Failed to reset perf event");
51            e.enable().expect("Failed to enable perf event");
52        }
53    }
54
55    /// Finish timing iteration. Disable recording.
56    fn end(&mut self, _benchmark: &str, _iteration: usize, _warmup: bool) {
57        for e in &mut self.events {
58            e.disable().expect("Failed to disable perf event");
59        }
60    }
61
62    /// Report data after the timing iteration.
63    fn report(&mut self) -> HashMap<String, Value> {
64        let mut values = HashMap::new();
65        for (i, e) in self.events.iter().enumerate() {
66            let v = e.read().unwrap().value as f32;
67            values.insert(self.event_names[i].clone(), v.into());
68        }
69        values
70    }
71}