Reformat, fix a bug due to confusing p and pointer in calibrate two thread and add relaod support
This commit is contained in:
parent
d47a7167ff
commit
daaca820fd
@ -1,12 +1,16 @@
|
|||||||
use core::sync::atomic::{AtomicBool,Ordering};
|
use cache_utils::calibration::{
|
||||||
|
calibrate_fixed_freq_2_thread, flush_and_reload, load_and_flush, only_flush, only_reload,
|
||||||
|
reload_and_flush, CalibrateOperation2T, HistParams, Verbosity, CFLUSH_BUCKET_NUMBER,
|
||||||
|
CFLUSH_BUCKET_SIZE, CFLUSH_NUM_ITER,
|
||||||
|
};
|
||||||
|
use cache_utils::mmap::MMappedMemory;
|
||||||
|
use cache_utils::{flush, maccess, noop};
|
||||||
use core::sync::atomic::spin_loop_hint;
|
use core::sync::atomic::spin_loop_hint;
|
||||||
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use nix::sched::{sched_getaffinity, CpuSet};
|
||||||
|
use nix::unistd::Pid;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use cache_utils::mmap::MMappedMemory;
|
|
||||||
use nix::sched::{CpuSet, sched_getaffinity};
|
|
||||||
use cache_utils::calibration::{calibrate_fixed_freq_2_thread, CalibrateOperation2T, load_and_flush, HistParams, CFLUSH_BUCKET_NUMBER, CFLUSH_BUCKET_SIZE, CFLUSH_NUM_ITER, Verbosity, only_flush};
|
|
||||||
use cache_utils::{maccess, noop, flush};
|
|
||||||
use nix::unistd::Pid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
fn wait(turn_lock: &AtomicBool, turn: bool) {
|
fn wait(turn_lock: &AtomicBool, turn: bool) {
|
||||||
@ -117,54 +121,79 @@ fn main() {
|
|||||||
if pointer as usize & (cache_line_size - 1) != 0 {
|
if pointer as usize & (cache_line_size - 1) != 0 {
|
||||||
panic!("not aligned nicely");
|
panic!("not aligned nicely");
|
||||||
}
|
}
|
||||||
calibrate_fixed_freq_2_thread(pointer,
|
calibrate_fixed_freq_2_thread(
|
||||||
64,
|
pointer,
|
||||||
array.len() as isize,
|
64,
|
||||||
&mut core_pairs.into_iter(),
|
array.len() as isize,
|
||||||
&[
|
&mut core_pairs.into_iter(),
|
||||||
CalibrateOperation2T {
|
&[
|
||||||
prepare: multiple_access,
|
CalibrateOperation2T {
|
||||||
op: only_flush,
|
prepare: multiple_access,
|
||||||
name: "clflush_remote_hit",
|
op: only_flush,
|
||||||
display_name: "clflush remote hit",
|
name: "clflush_remote_hit",
|
||||||
},
|
display_name: "clflush remote hit",
|
||||||
CalibrateOperation2T {
|
},
|
||||||
prepare: multiple_access,
|
CalibrateOperation2T {
|
||||||
op: load_and_flush,
|
prepare: multiple_access,
|
||||||
name: "clflush_shared_hit",
|
op: load_and_flush,
|
||||||
display_name: "clflush shared hit",
|
name: "clflush_shared_hit",
|
||||||
},
|
display_name: "clflush shared hit",
|
||||||
CalibrateOperation2T {
|
},
|
||||||
prepare: flush,
|
CalibrateOperation2T {
|
||||||
op: only_flush,
|
prepare: flush,
|
||||||
name: "clflush_miss_f",
|
op: only_flush,
|
||||||
display_name: "clflush miss - f",
|
name: "clflush_miss_f",
|
||||||
},
|
display_name: "clflush miss - f",
|
||||||
CalibrateOperation2T {
|
},
|
||||||
prepare: flush,
|
CalibrateOperation2T {
|
||||||
op: load_and_flush,
|
prepare: flush,
|
||||||
name: "clflush_local_hit_f",
|
op: load_and_flush,
|
||||||
display_name: "clflush local hit - f",
|
name: "clflush_local_hit_f",
|
||||||
},
|
display_name: "clflush local hit - f",
|
||||||
CalibrateOperation2T {
|
},
|
||||||
prepare: noop::<u8>,
|
CalibrateOperation2T {
|
||||||
op: only_flush,
|
prepare: noop::<u8>,
|
||||||
name: "clflush_miss_n",
|
op: only_flush,
|
||||||
display_name: "clflush miss - n",
|
name: "clflush_miss_n",
|
||||||
},
|
display_name: "clflush miss - n",
|
||||||
CalibrateOperation2T {
|
},
|
||||||
prepare: noop::<u8>,
|
CalibrateOperation2T {
|
||||||
op: load_and_flush,
|
prepare: noop::<u8>,
|
||||||
name: "clflush_local_hit_n",
|
op: load_and_flush,
|
||||||
display_name: "clflush local hit - n",
|
name: "clflush_local_hit_n",
|
||||||
},
|
display_name: "clflush local hit - n",
|
||||||
],
|
},
|
||||||
HistParams {
|
CalibrateOperation2T {
|
||||||
bucket_number: CFLUSH_BUCKET_NUMBER,
|
prepare: noop::<u8>,
|
||||||
bucket_size: CFLUSH_BUCKET_SIZE,
|
op: flush_and_reload,
|
||||||
iterations: CFLUSH_NUM_ITER,
|
name: "reload_miss",
|
||||||
},
|
display_name: "reload miss",
|
||||||
verbose_level,
|
},
|
||||||
|
CalibrateOperation2T {
|
||||||
|
prepare: multiple_access,
|
||||||
|
op: reload_and_flush,
|
||||||
|
name: "reload_remote_hit",
|
||||||
|
display_name: "reload remote hit",
|
||||||
|
},
|
||||||
|
CalibrateOperation2T {
|
||||||
|
prepare: multiple_access,
|
||||||
|
op: only_reload,
|
||||||
|
name: "reload_shared_hit",
|
||||||
|
display_name: "reload shared hit",
|
||||||
|
},
|
||||||
|
CalibrateOperation2T {
|
||||||
|
prepare: noop::<u8>,
|
||||||
|
op: only_reload,
|
||||||
|
name: "reload_local_hit",
|
||||||
|
display_name: "reload local hit",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
HistParams {
|
||||||
|
bucket_number: CFLUSH_BUCKET_NUMBER,
|
||||||
|
bucket_size: CFLUSH_BUCKET_SIZE,
|
||||||
|
iterations: CFLUSH_NUM_ITER,
|
||||||
|
},
|
||||||
|
verbose_level,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#![allow(clippy::missing_safety_doc)]
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
|
||||||
use crate::complex_addressing::{cache_slicing};
|
use crate::complex_addressing::cache_slicing;
|
||||||
use crate::{flush, maccess, rdtsc_fence};
|
use crate::{flush, maccess, rdtsc_fence};
|
||||||
|
|
||||||
use cpuid::MicroArchitecture;
|
use cpuid::MicroArchitecture;
|
||||||
@ -18,24 +18,23 @@ use nix::unistd::Pid;
|
|||||||
//#[cfg(feature = "use_std")]
|
//#[cfg(feature = "use_std")]
|
||||||
//use nix::Error::Sys;
|
//use nix::Error::Sys;
|
||||||
#[cfg(feature = "use_std")]
|
#[cfg(feature = "use_std")]
|
||||||
|
use nix::Error;
|
||||||
|
#[cfg(feature = "use_std")]
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
#[cfg(feature = "use_std")]
|
#[cfg(feature = "use_std")]
|
||||||
use std::thread;
|
use std::thread;
|
||||||
#[cfg(feature = "use_std")]
|
|
||||||
use nix::Error;
|
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use crate::calibration::Verbosity::*;
|
use crate::calibration::Verbosity::*;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
|
use core::ptr::null_mut;
|
||||||
|
use core::sync::atomic::{spin_loop_hint, AtomicBool, AtomicPtr, Ordering};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use core::sync::atomic::{AtomicPtr, AtomicBool, Ordering, spin_loop_hint};
|
|
||||||
use core::ptr::{/*null,*/ null_mut};
|
|
||||||
|
|
||||||
use atomic::Atomic;
|
use atomic::Atomic;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Ord, PartialOrd, Eq, PartialEq)]
|
#[derive(Ord, PartialOrd, Eq, PartialEq)]
|
||||||
pub enum Verbosity {
|
pub enum Verbosity {
|
||||||
NoOutput,
|
NoOutput,
|
||||||
@ -61,6 +60,12 @@ pub unsafe fn flush_and_reload(p: *const u8) -> u64 {
|
|||||||
only_reload(p)
|
only_reload(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn reload_and_flush(p: *const u8) -> u64 {
|
||||||
|
let r = only_reload(p);
|
||||||
|
flush(p);
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
pub unsafe fn only_flush(p: *const u8) -> u64 {
|
pub unsafe fn only_flush(p: *const u8) -> u64 {
|
||||||
let t = rdtsc_fence();
|
let t = rdtsc_fence();
|
||||||
flush(p);
|
flush(p);
|
||||||
@ -272,8 +277,6 @@ fn calibrate_impl_fixed_freq(
|
|||||||
let to_bucket = |time: u64| -> usize { time as usize / hist_params.bucket_size };
|
let to_bucket = |time: u64| -> usize { time as usize / hist_params.bucket_size };
|
||||||
let from_bucket = |bucket: usize| -> u64 { (bucket * hist_params.bucket_size) as u64 };
|
let from_bucket = |bucket: usize| -> u64 { (bucket * hist_params.bucket_size) as u64 };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let slicing = if let Some(uarch) = MicroArchitecture::get_micro_architecture() {
|
let slicing = if let Some(uarch) = MicroArchitecture::get_micro_architecture() {
|
||||||
Some(cache_slicing(uarch, 8))
|
Some(cache_slicing(uarch, 8))
|
||||||
} else {
|
} else {
|
||||||
@ -446,7 +449,7 @@ pub struct CalibrateResult2T {
|
|||||||
pub helper_core: usize,
|
pub helper_core: usize,
|
||||||
pub res: Result<Vec<CalibrateResult>, nix::Error>, // TODO
|
pub res: Result<Vec<CalibrateResult>, nix::Error>, // TODO
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait(turn_lock: &AtomicBool, turn: bool) {
|
fn wait(turn_lock: &AtomicBool, turn: bool) {
|
||||||
@ -470,7 +473,15 @@ pub unsafe fn calibrate_fixed_freq_2_thread<I: Iterator<Item = (usize, usize)>>(
|
|||||||
hist_params: HistParams,
|
hist_params: HistParams,
|
||||||
verbosity_level: Verbosity,
|
verbosity_level: Verbosity,
|
||||||
) -> Vec<CalibrateResult2T> {
|
) -> Vec<CalibrateResult2T> {
|
||||||
calibrate_fixed_freq_2_thread_impl(p, increment, len, cores, operations, hist_params, verbosity_level)
|
calibrate_fixed_freq_2_thread_impl(
|
||||||
|
p,
|
||||||
|
increment,
|
||||||
|
len,
|
||||||
|
cores,
|
||||||
|
operations,
|
||||||
|
hist_params,
|
||||||
|
verbosity_level,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "use_std")]
|
#[cfg(feature = "use_std")]
|
||||||
@ -514,15 +525,13 @@ fn calibrate_fixed_freq_2_thread_impl<I: Iterator<Item = (usize, usize)>>(
|
|||||||
|
|
||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
|
|
||||||
let helper_thread_params = Arc::new(HelperThreadParams{
|
let helper_thread_params = Arc::new(HelperThreadParams {
|
||||||
turn: AtomicBool::new(false),
|
turn: AtomicBool::new(false),
|
||||||
stop: AtomicBool::new(true),
|
stop: AtomicBool::new(true),
|
||||||
op: Atomic::new(operations[0].prepare),
|
op: Atomic::new(operations[0].prepare),
|
||||||
address: AtomicPtr::new(null_mut()),
|
address: AtomicPtr::new(null_mut()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if verbosity_level >= Thresholds {
|
if verbosity_level >= Thresholds {
|
||||||
print!("CSV: main_core, helper_core, address, ");
|
print!("CSV: main_core, helper_core, address, ");
|
||||||
if h.is_some() {
|
if h.is_some() {
|
||||||
@ -565,47 +574,57 @@ fn calibrate_fixed_freq_2_thread_impl<I: Iterator<Item = (usize, usize)>>(
|
|||||||
// set main thread affinity
|
// set main thread affinity
|
||||||
|
|
||||||
if verbosity_level >= Thresholds {
|
if verbosity_level >= Thresholds {
|
||||||
println!("Calibration for main_core {}, helper {}.", main_core, helper_core);
|
println!(
|
||||||
|
"Calibration for main_core {}, helper {}.",
|
||||||
|
main_core, helper_core
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("Calibration for main_core {}, helper {}.", main_core, helper_core);
|
eprintln!(
|
||||||
|
"Calibration for main_core {}, helper {}.",
|
||||||
|
main_core, helper_core
|
||||||
|
);
|
||||||
|
|
||||||
let mut core = CpuSet::new();
|
let mut core = CpuSet::new();
|
||||||
match core.set(main_core) {
|
match core.set(main_core) {
|
||||||
Ok(_) => {},
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
ret.push(CalibrateResult2T{main_core, helper_core, res:Err(e)});
|
ret.push(CalibrateResult2T {
|
||||||
|
main_core,
|
||||||
|
helper_core,
|
||||||
|
res: Err(e),
|
||||||
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match sched_setaffinity(Pid::from_raw(0), &core) {
|
match sched_setaffinity(Pid::from_raw(0), &core) {
|
||||||
Ok(_) => {},
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
ret.push(CalibrateResult2T{main_core, helper_core, res:Err(e)});
|
ret.push(CalibrateResult2T {
|
||||||
|
main_core,
|
||||||
|
helper_core,
|
||||||
|
res: Err(e),
|
||||||
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
helper_thread_params.stop.store(false, Ordering::Relaxed);
|
helper_thread_params.stop.store(false, Ordering::Relaxed);
|
||||||
// set up the helper thread
|
// set up the helper thread
|
||||||
|
|
||||||
let htp = helper_thread_params.clone();
|
let htp = helper_thread_params.clone();
|
||||||
let hc = helper_core;
|
let hc = helper_core;
|
||||||
let helper_thread = thread::spawn(move || {
|
let helper_thread = thread::spawn(move || calibrate_fixed_freq_2_thread_helper(htp, hc));
|
||||||
calibrate_fixed_freq_2_thread_helper(htp, hc)
|
|
||||||
});
|
|
||||||
|
|
||||||
// do the calibration
|
// do the calibration
|
||||||
let mut calibrate_result_vec = Vec::new();
|
let mut calibrate_result_vec = Vec::new();
|
||||||
|
|
||||||
for i in (0..len).step_by(increment) {
|
for i in (0..len).step_by(increment) {
|
||||||
|
|
||||||
let pointer = unsafe { p.offset(i) };
|
let pointer = unsafe { p.offset(i) };
|
||||||
helper_thread_params.address.store(p as *mut u8, Ordering::Relaxed);
|
helper_thread_params
|
||||||
|
.address
|
||||||
|
.store(pointer as *mut u8, Ordering::Relaxed);
|
||||||
|
|
||||||
let hash = h.map(|h| h(pointer as usize));
|
let hash = h.map(|h| h(pointer as usize));
|
||||||
|
|
||||||
@ -627,8 +646,6 @@ fn calibrate_fixed_freq_2_thread_impl<I: Iterator<Item = (usize, usize)>>(
|
|||||||
};
|
};
|
||||||
calibrate_result.histogram.reserve(operations.len());
|
calibrate_result.histogram.reserve(operations.len());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for op in operations {
|
for op in operations {
|
||||||
helper_thread_params.op.store(op.prepare, Ordering::Relaxed);
|
helper_thread_params.op.store(op.prepare, Ordering::Relaxed);
|
||||||
let mut hist = vec![0; hist_params.bucket_number];
|
let mut hist = vec![0; hist_params.bucket_number];
|
||||||
@ -718,10 +735,10 @@ fn calibrate_fixed_freq_2_thread_impl<I: Iterator<Item = (usize, usize)>>(
|
|||||||
calibrate_result_vec.push(calibrate_result);
|
calibrate_result_vec.push(calibrate_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push(CalibrateResult2T{
|
ret.push(CalibrateResult2T {
|
||||||
main_core,
|
main_core,
|
||||||
helper_core,
|
helper_core,
|
||||||
res: Ok(calibrate_result_vec)
|
res: Ok(calibrate_result_vec),
|
||||||
});
|
});
|
||||||
// terminate the thread
|
// terminate the thread
|
||||||
helper_thread_params.stop.store(true, Ordering::Relaxed);
|
helper_thread_params.stop.store(true, Ordering::Relaxed);
|
||||||
@ -729,7 +746,6 @@ fn calibrate_fixed_freq_2_thread_impl<I: Iterator<Item = (usize, usize)>>(
|
|||||||
wait(&helper_thread_params.turn, false);
|
wait(&helper_thread_params.turn, false);
|
||||||
// join thread.
|
// join thread.
|
||||||
helper_thread.join();
|
helper_thread.join();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sched_setaffinity(Pid::from_raw(0), &old).unwrap();
|
sched_setaffinity(Pid::from_raw(0), &old).unwrap();
|
||||||
@ -754,17 +770,16 @@ fn calibrate_fixed_freq_2_thread_helper(
|
|||||||
// set thread affinity
|
// set thread affinity
|
||||||
let mut core = CpuSet::new();
|
let mut core = CpuSet::new();
|
||||||
match core.set(helper_core) {
|
match core.set(helper_core) {
|
||||||
Ok(_) => {},
|
Ok(_) => {}
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match sched_setaffinity(Pid::from_raw(0), &core) {
|
match sched_setaffinity(Pid::from_raw(0), &core) {
|
||||||
Ok(_) => {},
|
Ok(_) => {}
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,7 +793,7 @@ fn calibrate_fixed_freq_2_thread_helper(
|
|||||||
// get the relevant parameters
|
// get the relevant parameters
|
||||||
let addr: *const u8 = params.address.load(Ordering::Relaxed);
|
let addr: *const u8 = params.address.load(Ordering::Relaxed);
|
||||||
let op = params.op.load(Ordering::Relaxed);
|
let op = params.op.load(Ordering::Relaxed);
|
||||||
unsafe {op(addr)};
|
unsafe { op(addr) };
|
||||||
// release lock
|
// release lock
|
||||||
next(¶ms.turn);
|
next(¶ms.turn);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user