1use perf_event::events::{Cache, CacheOp, CacheResult, Hardware, WhichCache};
2use perf_event::{Builder, Group};
3
4fn main() -> std::io::Result<()> {
5 const ACCESS: Cache = Cache {
6 which: WhichCache::L1D,
7 operation: CacheOp::READ,
8 result: CacheResult::ACCESS,
9 };
10 const MISS: Cache = Cache {
11 result: CacheResult::MISS,
12 ..ACCESS
13 };
14
15 let mut group = Group::new()?;
16 let access_counter = Builder::new().group(&mut group).kind(ACCESS).build()?;
17 let miss_counter = Builder::new().group(&mut group).kind(MISS).build()?;
18 let branches = Builder::new()
19 .group(&mut group)
20 .kind(Hardware::BRANCH_INSTRUCTIONS)
21 .build()?;
22 let missed_branches = Builder::new()
23 .group(&mut group)
24 .kind(Hardware::BRANCH_MISSES)
25 .build()?;
26 let insns = Builder::new()
27 .group(&mut group)
28 .kind(Hardware::INSTRUCTIONS)
29 .build()?;
30 let cycles = Builder::new()
31 .group(&mut group)
32 .kind(Hardware::CPU_CYCLES)
33 .build()?;
34
35 let mut vec = (0..=100000).collect::<Vec<_>>();
45
46 group.enable()?;
47 vec.sort();
48 println!("{:?}", &vec[0..10]);
49 group.disable()?;
50
51 let counts = group.read()?;
52
53 println!(
54 "enabled for {}ns, actually running for {}ns",
55 counts.time_enabled(),
56 counts.time_running()
57 );
58
59 if counts.time_running() == 0 {
60 println!("Group was never running; no results available.");
61 return Ok(());
62 }
63
64 if counts.time_running() < counts.time_enabled() {
65 println!("Counts cover only a portion of the execution.");
66 }
67
68 println!(
69 "L1D cache misses/references: {} / {} ({:.0}%)",
70 counts[&miss_counter],
71 counts[&access_counter],
72 (counts[&miss_counter] as f64 / counts[&access_counter] as f64) * 100.0
73 );
74
75 println!(
76 "branch prediction misses/total: {} / {} ({:.0}%)",
77 counts[&missed_branches],
78 counts[&branches],
79 (counts[&missed_branches] as f64 / counts[&branches] as f64) * 100.0
80 );
81
82 println!(
83 "{} instructions, {} cycles ({:.2} cpi)",
84 counts[&insns],
85 counts[&cycles],
86 counts[&cycles] as f64 / counts[&insns] as f64
87 );
88
89 for (id, value) in &counts {
91 println!("Counter id {} has value {}", id, value);
92 }
93
94 Ok(())
95}