Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nviennot
GitHub Repository: nviennot/core-to-core-latency
Path: blob/main/src/utils.rs
228 views
1
use std::time::Duration;
2
use quanta::Clock;
3
use crate::bench::Count;
4
5
pub fn black_box<T>(dummy: T) -> T {
6
unsafe { std::ptr::read_volatile(&dummy) }
7
}
8
9
pub fn delay_cycles(num_iterations: usize) {
10
static VALUE: usize = 0;
11
for _ in 0..num_iterations {
12
// unsafe { std::arch::asm!("nop"); } might not work on all platforms
13
black_box(&VALUE);
14
}
15
}
16
17
// Returns the duration of doing `num_iterations` of clock.raw()
18
pub fn clock_read_overhead_sum(clock: &Clock, num_iterations: Count) -> Duration {
19
let start = clock.raw();
20
for _ in 0..(num_iterations-1) {
21
black_box(clock.raw());
22
}
23
let end = clock.raw();
24
clock.delta(start, end)
25
}
26
27
// This big feature condition is on CpuId::default(), we'll use the same.
28
#[cfg(any(
29
all(target_arch = "x86", not(target_env = "sgx"), target_feature = "sse"),
30
all(target_arch = "x86_64", not(target_env = "sgx"))
31
))]
32
pub fn get_cpuid() -> Option<raw_cpuid::CpuId> {
33
Some(raw_cpuid::CpuId::default())
34
}
35
36
#[cfg(not(any(
37
all(target_arch = "x86", not(target_env = "sgx"), target_feature = "sse"),
38
all(target_arch = "x86_64", not(target_env = "sgx"))
39
)))]
40
pub fn get_cpuid() -> Option<raw_cpuid::CpuId> {
41
None
42
}
43
44
pub fn assert_rdtsc_usable(clock: &quanta::Clock) {
45
let cpuid = get_cpuid().expect("This benchmark is only compatible with x86");
46
47
assert!(cpuid.get_advanced_power_mgmt_info().expect("CPUID failed").has_invariant_tsc(),
48
"This benchmark only runs with a TscInvariant=true");
49
50
const NUM_ITERS: Count = 10_000;
51
let clock_read_overhead = clock_read_overhead_sum(&clock, NUM_ITERS).as_nanos() as f64 / NUM_ITERS as f64;
52
eprintln!("Reading the clock via RDTSC takes {:.2}ns", clock_read_overhead);
53
assert!((0.1..1000.0).contains(&clock_read_overhead), "The timing to read the clock is either not-consistant or too slow");
54
}
55
56
pub fn get_cpu_brand() -> Option<String> {
57
get_cpuid()
58
.and_then(|c| c.get_processor_brand_string())
59
.map(|c| c.as_str().to_string())
60
}
61
62
pub fn show_cpuid_info() {
63
if let Some(brand) = get_cpu_brand() {
64
eprintln!("CPU: {}", brand);
65
}
66
}
67
68