Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nviennot
GitHub Repository: nviennot/core-to-core-latency
Path: blob/main/src/bench/read_write.rs
228 views
1
use cache_padded::CachePadded;
2
use core_affinity::CoreId;
3
use std::sync::Barrier;
4
use std::sync::atomic::{Ordering, AtomicBool};
5
use quanta::Clock;
6
7
use super::Count;
8
9
pub struct Bench {
10
barrier: CachePadded<Barrier>,
11
owned_by_ping: CachePadded<AtomicBool>,
12
owned_by_pong: CachePadded<AtomicBool>
13
}
14
15
impl Bench {
16
pub fn new() -> Self {
17
Self {
18
barrier: CachePadded::new(Barrier::new(2)),
19
owned_by_ping: Default::default(),
20
owned_by_pong: Default::default(),
21
}
22
}
23
}
24
25
impl super::Bench for Bench {
26
// Thread 1 writes to cache line 1 and read cache line 2
27
// Thread 2 writes to cache line 2 and read cache line 1
28
fn run(
29
&self,
30
(ping_core, pong_core): (CoreId, CoreId),
31
clock: &Clock,
32
num_round_trips: Count,
33
num_samples: Count,
34
) -> Vec<f64> {
35
let state = self;
36
37
crossbeam_utils::thread::scope(|s| {
38
let pong = s.spawn(move |_| {
39
core_affinity::set_for_current(pong_core);
40
state.barrier.wait();
41
let mut v = false;
42
for _ in 0..(num_round_trips*num_samples) {
43
// Acquire -> Release is important to enforce a causal dependency
44
// This has no effect on x86
45
while state.owned_by_ping.load(Ordering::Acquire) != v {}
46
state.owned_by_pong.store(!v, Ordering::Release);
47
v = !v;
48
}
49
});
50
51
let ping = s.spawn(move |_| {
52
let mut results = Vec::with_capacity(num_samples as usize);
53
54
core_affinity::set_for_current(ping_core);
55
state.barrier.wait();
56
let mut v = true;
57
for _ in 0..num_samples {
58
let start = clock.raw();
59
for _ in 0..num_round_trips {
60
// Acquire -> Release is important to enforce a causal dependency
61
// This has no effect on x86
62
while state.owned_by_pong.load(Ordering::Acquire) != v {}
63
state.owned_by_ping.store(v, Ordering::Release);
64
v = !v;
65
}
66
let end = clock.raw();
67
let duration = clock.delta(start, end).as_nanos();
68
results.push(duration as f64 / num_round_trips as f64 / 2.0);
69
}
70
results
71
});
72
73
pong.join().unwrap();
74
ping.join().unwrap()
75
}).unwrap()
76
}
77
}
78
79