Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nviennot
GitHub Repository: nviennot/core-to-core-latency
Path: blob/main/src/bench/cas.rs
228 views
1
use core_affinity::CoreId;
2
use std::sync::Barrier;
3
use std::sync::atomic::{AtomicBool, Ordering};
4
use quanta::Clock;
5
use super::Count;
6
7
const PING: bool = false;
8
const PONG: bool = true;
9
10
pub struct Bench {
11
barrier: Barrier,
12
flag: AtomicBool,
13
}
14
15
impl Bench {
16
pub fn new() -> Self {
17
Self {
18
barrier: Barrier::new(2),
19
flag: AtomicBool::new(PING),
20
}
21
}
22
}
23
24
impl super::Bench for Bench {
25
// The two threads modify the same cacheline.
26
// This is useful to benchmark spinlock performance.
27
fn run(
28
&self,
29
(ping_core, pong_core): (CoreId, CoreId),
30
clock: &Clock,
31
num_round_trips: Count,
32
num_samples: Count,
33
) -> Vec<f64> {
34
let state = self;
35
36
crossbeam_utils::thread::scope(|s| {
37
let pong = s.spawn(move |_| {
38
core_affinity::set_for_current(pong_core);
39
40
state.barrier.wait();
41
for _ in 0..(num_round_trips*num_samples) {
42
while state.flag.compare_exchange(PING, PONG, Ordering::Relaxed, Ordering::Relaxed).is_err() {}
43
}
44
});
45
46
let ping = s.spawn(move |_| {
47
core_affinity::set_for_current(ping_core);
48
49
let mut results = Vec::with_capacity(num_samples as usize);
50
51
state.barrier.wait();
52
53
for _ in 0..num_samples {
54
let start = clock.raw();
55
for _ in 0..num_round_trips {
56
while state.flag.compare_exchange(PONG, PING, Ordering::Relaxed, Ordering::Relaxed).is_err() {}
57
}
58
let end = clock.raw();
59
let duration = clock.delta(start, end).as_nanos();
60
results.push(duration as f64 / num_round_trips as f64 / 2.0);
61
}
62
63
results
64
});
65
66
pong.join().unwrap();
67
ping.join().unwrap()
68
}).unwrap()
69
}
70
}
71
72