1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
use std::{
fs,
fmt::Write,
hint::black_box,
time::{Duration, Instant},
};
fn read_energy_uj() -> u64 {
fs::read_to_string("/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj")
.map(|s| s.trim().parse().unwrap_or(0))
.unwrap_or_else(|e| {
eprintln!("Failed to open energy counter (Are you running with sudo?): {e}");
0
})
}
pub fn bench(name: String, f: fn(&[u8]) -> usize, buffer: &[u8], out: &mut String) {
let mut budget: isize = 5_000_000_000;
let mut best = Duration::MAX;
let mut best_energy = u64::MAX;
writeln!(out, " <benchmark name=\"{}\">", name).unwrap();
let res = f(buffer);
while budget > 0 {
let energy_start = read_energy_uj();
let start = Instant::now();
let res = f(buffer);
let elapsed = start.elapsed();
best = best.min(elapsed);
best_energy = best_energy.min(read_energy_uj() - energy_start);
budget -= elapsed.as_nanos() as isize;
black_box(res);
}
writeln!(out,
"\x20 <res>{}</res>\n\
\x20 <time unit=\"ns\">{}</time>\n\
\x20 <throughput unit=\"MiB/s\">{}</throughput>",
res,
best.as_nanos(),
(buffer.len() as f64 / (1024.0 * 1024.0)) / best.as_secs_f64(),
).unwrap();
if best_energy != 0 {
writeln!(out,
"\x20 <energy-consumption unit=\"J/GiB\">{}</energy-consumption>",
((best_energy as f64) / (1000.0 * 1000.0)) / (buffer.len() as f64 / (1024.0 * 1024.0 * 1024.0)),
).unwrap();
}
writeln!(out,
"\x20 </benchmark>",
).unwrap();
}
|