@@ -4,12 +4,14 @@ use perf_event::events::Hardware;
4
4
use perf_event:: { Builder , Counter , Group } ;
5
5
use std:: time:: Instant ;
6
6
7
+ /// A collection of CPU performance counters.
8
+ /// The counters are optional, because some CPUs are not able to record them.
7
9
struct Counters {
8
- cycles : Counter ,
9
- instructions : Counter ,
10
- branch_misses : Counter ,
11
- cache_misses : Counter ,
12
- cache_references : Counter ,
10
+ cycles : Option < Counter > ,
11
+ instructions : Option < Counter > ,
12
+ branch_misses : Option < Counter > ,
13
+ cache_misses : Option < Counter > ,
14
+ cache_references : Option < Counter > ,
13
15
}
14
16
15
17
/// Benchmarks a single function generated by `benchmark_constructor`.
@@ -48,11 +50,11 @@ pub fn benchmark_function<F: Fn() -> Bench + 'static, R, Bench: FnOnce() -> R +
48
50
black_box ( output) ;
49
51
50
52
let result = BenchmarkStats {
51
- cycles : measurement [ & counters. cycles ] ,
52
- instructions : measurement [ & counters. instructions ] ,
53
- branch_misses : measurement [ & counters. branch_misses ] ,
54
- cache_misses : measurement [ & counters. cache_misses ] ,
55
- cache_references : measurement [ & counters. cache_references ] ,
53
+ cycles : counters. cycles . map ( |c| measurement [ & c ] ) ,
54
+ instructions : counters. instructions . map ( |c| measurement [ & c ] ) ,
55
+ branch_misses : counters. branch_misses . map ( |c| measurement [ & c ] ) ,
56
+ cache_misses : counters. cache_misses . map ( |c| measurement [ & c ] ) ,
57
+ cache_references : counters. cache_references . map ( |c| measurement [ & c ] ) ,
56
58
wall_time : duration,
57
59
} ;
58
60
Ok ( result)
@@ -77,19 +79,23 @@ Try lowering it with `sudo bash -c 'echo -1 > /proc/sys/kernel/perf_event_parano
77
79
}
78
80
79
81
fn prepare_counters ( group : & mut Group ) -> anyhow:: Result < Counters > {
80
- let mut add_event = |event : Hardware | {
81
- Builder :: new ( )
82
- . group ( group)
83
- . kind ( event)
84
- . build ( )
85
- . map_err ( |error| anyhow:: anyhow!( "Could not add counter {:?}: {:?}" , event, error) )
82
+ let mut add_event = |event : Hardware | match Builder :: new ( ) . group ( group) . kind ( event) . build ( ) {
83
+ Ok ( counter) => Some ( counter) ,
84
+ Err ( error) => {
85
+ log:: warn!(
86
+ "Could not add counter {:?}: {:?}. Maybe the CPU doesn't support it?" ,
87
+ event,
88
+ error
89
+ ) ;
90
+ None
91
+ }
86
92
} ;
87
93
88
- let cycles = add_event ( Hardware :: CPU_CYCLES ) ? ;
89
- let instructions = add_event ( Hardware :: INSTRUCTIONS ) ? ;
90
- let branch_misses = add_event ( Hardware :: BRANCH_MISSES ) ? ;
91
- let cache_misses = add_event ( Hardware :: CACHE_MISSES ) ? ;
92
- let cache_references = add_event ( Hardware :: CACHE_REFERENCES ) ? ;
94
+ let cycles = add_event ( Hardware :: CPU_CYCLES ) ;
95
+ let instructions = add_event ( Hardware :: INSTRUCTIONS ) ;
96
+ let branch_misses = add_event ( Hardware :: BRANCH_MISSES ) ;
97
+ let cache_misses = add_event ( Hardware :: CACHE_MISSES ) ;
98
+ let cache_references = add_event ( Hardware :: CACHE_REFERENCES ) ;
93
99
94
100
Ok ( Counters {
95
101
cycles,
0 commit comments