Hotfix - Use naive F+R instead of F+R
F+R currently has a calibration bug
This commit is contained in:
parent
28f75075e3
commit
3022794752
@ -1,15 +1,18 @@
|
||||
use crate::Probe::{Flush, Load};
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
use crate::Probe::{Flush, FullFlush, Load};
|
||||
use basic_timing_cache_channel::{TopologyAwareError, TopologyAwareTimingChannel};
|
||||
use cache_side_channel::CacheStatus::Hit;
|
||||
use cache_side_channel::{
|
||||
set_affinity, CacheStatus, CoreSpec, MultipleAddrCacheSideChannel, SingleAddrCacheSideChannel,
|
||||
};
|
||||
use cache_utils::calibration::PAGE_LEN;
|
||||
use cache_utils::calibration::{Threshold, PAGE_LEN};
|
||||
use cache_utils::mmap::MMappedMemory;
|
||||
use flush_flush::{FFHandle, FFPrimitives, FlushAndFlush};
|
||||
use flush_reload::naive::{NFRHandle, NaiveFlushAndReload};
|
||||
use flush_reload::{FRHandle, FRPrimitives, FlushAndReload};
|
||||
use nix::sys::stat::stat;
|
||||
use rand::seq::SliceRandom;
|
||||
use std::fmt::{Display, Error, Formatter};
|
||||
use std::iter::{Cycle, Peekable};
|
||||
use std::ops::Range;
|
||||
|
||||
@ -20,10 +23,10 @@ pub const PAGE_CACHELINE_LEN: usize = PAGE_LEN / CACHE_LINE_LEN;
|
||||
pub struct Prober {
|
||||
pages: Vec<MMappedMemory<u8>>,
|
||||
ff_handles: Vec<Vec<FFHandle>>,
|
||||
fr_handles: Vec<Vec<FRHandle>>,
|
||||
fr_handles: Vec<Vec<NFRHandle>>,
|
||||
page_indexes: Peekable<Cycle<Range<usize>>>,
|
||||
ff_channel: FlushAndFlush,
|
||||
fr_channel: FlushAndReload,
|
||||
fr_channel: NaiveFlushAndReload,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@ -33,12 +36,21 @@ pub enum Probe {
|
||||
FullFlush,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ProbeType {
|
||||
Load,
|
||||
Flush,
|
||||
FullFlush,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ProbePattern {
|
||||
pub pattern: Vec<usize>,
|
||||
pub probe: Probe,
|
||||
}
|
||||
|
||||
enum ProberError {
|
||||
#[derive(Debug)]
|
||||
pub enum ProberError {
|
||||
NoMem(nix::Error),
|
||||
TopologyError(TopologyAwareError),
|
||||
Nix(nix::Error),
|
||||
@ -47,45 +59,57 @@ enum ProberError {
|
||||
/**
|
||||
Result of running a probe pattern num_iteration times,
|
||||
*/
|
||||
pub type SinglePR = u32;
|
||||
pub type FullPR = Vec<u32>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProbeResult {
|
||||
Load(u32),
|
||||
Flush(u32),
|
||||
FullFlush(Vec<u32>),
|
||||
Load(SinglePR),
|
||||
Flush(SinglePR),
|
||||
FullFlush(FullPR),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ProbePatternResult {
|
||||
pub num_iteration: u32,
|
||||
pub pattern_result: Vec<u32>,
|
||||
pub probe_result: ProbeResult,
|
||||
}
|
||||
|
||||
struct DPRItem {
|
||||
pattern_result: Vec<u32>,
|
||||
probe_result: u32,
|
||||
#[derive(Debug)]
|
||||
pub struct DPRItem<PR> {
|
||||
pub pattern_result: Vec<u32>,
|
||||
pub probe_result: PR,
|
||||
}
|
||||
|
||||
struct DualProbeResult {
|
||||
probe_offset: usize,
|
||||
load: DPRItem,
|
||||
flush: DPRItem,
|
||||
#[derive(Debug)]
|
||||
pub struct DualProbeResult {
|
||||
pub probe_offset: usize,
|
||||
pub load: DPRItem<SinglePR>,
|
||||
pub flush: DPRItem<SinglePR>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FullPageDualProbeResults {
|
||||
num_iteration: u32,
|
||||
results: Vec<DualProbeResult>,
|
||||
pub pattern: Vec<usize>,
|
||||
pub num_iteration: u32,
|
||||
pub single_probe_results: Vec<DualProbeResult>,
|
||||
pub full_flush_results: DPRItem<FullPR>,
|
||||
}
|
||||
|
||||
struct SingleProbeResult {
|
||||
probe_offset: usize,
|
||||
pattern_result: Vec<u32>,
|
||||
probe_result: u32,
|
||||
#[derive(Debug)]
|
||||
pub struct SingleProbeResult {
|
||||
pub probe_offset: usize,
|
||||
pub pattern_result: Vec<u32>,
|
||||
pub probe_result: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FullPageSingleProbeResult {
|
||||
probe_type: Probe,
|
||||
num_iteration: u32,
|
||||
results: Vec<SingleProbeResult>,
|
||||
pub pattern: Vec<usize>,
|
||||
pub probe_type: ProbeType,
|
||||
pub num_iteration: u32,
|
||||
pub results: Vec<SingleProbeResult>,
|
||||
}
|
||||
|
||||
// Helper function
|
||||
@ -106,7 +130,7 @@ fn max_stride(offset: usize, len: usize) -> (isize, isize) {
|
||||
}
|
||||
|
||||
impl Prober {
|
||||
fn new(num_pages: usize) -> Result<Prober, ProberError> {
|
||||
pub fn new(num_pages: usize) -> Result<Prober, ProberError> {
|
||||
let mut vec = Vec::new();
|
||||
let mut handles = Vec::new();
|
||||
let (mut ff_channel, cpuset, core) = match FlushAndFlush::new_any_single_core() {
|
||||
@ -119,12 +143,17 @@ impl Prober {
|
||||
Ok(old) => old,
|
||||
Err(nixerr) => return Err(ProberError::Nix(nixerr)),
|
||||
};
|
||||
let mut fr_channel = NaiveFlushAndReload::new(Threshold {
|
||||
bucket_index: 250,
|
||||
miss_faster_than_hit: false,
|
||||
});
|
||||
/*
|
||||
let mut fr_channel = match FlushAndReload::new(core, core) {
|
||||
Ok(res) => res,
|
||||
Err(err) => {
|
||||
return Err(ProberError::TopologyError(err));
|
||||
}
|
||||
};
|
||||
};*/
|
||||
|
||||
for i in 0..num_pages {
|
||||
let mut p = match MMappedMemory::<u8>::try_new(PAGE_LEN, false) {
|
||||
@ -139,7 +168,7 @@ impl Prober {
|
||||
let page_addresses =
|
||||
((0..PAGE_LEN).step_by(CACHE_LINE_LEN)).map(|offset| &p[offset] as *const u8);
|
||||
let ff_page_handles = unsafe { ff_channel.calibrate(page_addresses.clone()) }.unwrap();
|
||||
let fr_page_handles = unsafe { fr_channel.calibrate(page_addresses) }.unwrap();
|
||||
let fr_page_handles = unsafe { fr_channel.calibrate_single(page_addresses) }.unwrap();
|
||||
|
||||
vec.push(p);
|
||||
handles.push((ff_page_handles, fr_page_handles));
|
||||
@ -151,6 +180,7 @@ impl Prober {
|
||||
|
||||
let mut ff_handles = Vec::new();
|
||||
let mut fr_handles = Vec::new();
|
||||
|
||||
for (ff_handle, fr_handle) in handles {
|
||||
ff_handles.push(ff_handle);
|
||||
fr_handles.push(fr_handle);
|
||||
@ -278,4 +308,179 @@ impl Prober {
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn full_page_probe_helper(
|
||||
&mut self,
|
||||
pattern: &mut ProbePattern,
|
||||
probe_type: ProbeType,
|
||||
num_iteration: u32,
|
||||
warmup: u32,
|
||||
) -> FullPageSingleProbeResult {
|
||||
let mut result = FullPageSingleProbeResult {
|
||||
pattern: pattern.pattern.clone(),
|
||||
probe_type,
|
||||
num_iteration,
|
||||
results: vec![],
|
||||
};
|
||||
for offset in 0..PAGE_CACHELINE_LEN {
|
||||
pattern.probe = match probe_type {
|
||||
ProbeType::Load => Probe::Load(offset),
|
||||
ProbeType::Flush => Probe::Flush(offset),
|
||||
ProbeType::FullFlush => FullFlush,
|
||||
};
|
||||
let r = self.probe_pattern(pattern, num_iteration, warmup);
|
||||
result.results.push(SingleProbeResult {
|
||||
probe_offset: offset,
|
||||
pattern_result: r.pattern_result,
|
||||
probe_result: match r.probe_result {
|
||||
ProbeResult::Load(r) => r,
|
||||
ProbeResult::Flush(r) => r,
|
||||
ProbeResult::FullFlush(r) => r[offset],
|
||||
},
|
||||
});
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn full_page_probe(
|
||||
&mut self,
|
||||
pattern: Vec<usize>,
|
||||
num_iteration: u32,
|
||||
warmup: u32,
|
||||
) -> FullPageDualProbeResults {
|
||||
let mut probe_pattern = ProbePattern {
|
||||
pattern: pattern,
|
||||
probe: Probe::FullFlush,
|
||||
};
|
||||
let res_flush = self.full_page_probe_helper(
|
||||
&mut probe_pattern,
|
||||
ProbeType::Flush,
|
||||
num_iteration,
|
||||
warmup,
|
||||
);
|
||||
let res_load =
|
||||
self.full_page_probe_helper(&mut probe_pattern, ProbeType::Load, num_iteration, warmup);
|
||||
probe_pattern.probe = FullFlush;
|
||||
let res_full_flush = self.probe_pattern(&probe_pattern, num_iteration, warmup);
|
||||
// TODO results
|
||||
|
||||
FullPageDualProbeResults {
|
||||
pattern: probe_pattern.pattern,
|
||||
num_iteration,
|
||||
single_probe_results: res_flush
|
||||
.results
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.zip(res_load.results.into_iter())
|
||||
.map(|((offset, flush), load)| DualProbeResult {
|
||||
probe_offset: offset,
|
||||
load: DPRItem {
|
||||
pattern_result: load.pattern_result,
|
||||
probe_result: load.probe_result,
|
||||
},
|
||||
flush: DPRItem {
|
||||
pattern_result: flush.pattern_result,
|
||||
probe_result: flush.probe_result,
|
||||
},
|
||||
})
|
||||
.collect(),
|
||||
full_flush_results: DPRItem {
|
||||
pattern_result: res_full_flush.pattern_result,
|
||||
probe_result: match res_full_flush.probe_result {
|
||||
ProbeResult::FullFlush(r) => r,
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for FullPageDualProbeResults {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let mut indices = vec![None; PAGE_CACHELINE_LEN];
|
||||
let pat_len = self.pattern.len();
|
||||
let divider = (PAGE_CACHELINE_LEN * self.num_iteration as usize) as f32;
|
||||
for (i, &offset) in self.pattern.iter().enumerate() {
|
||||
indices[offset] = Some(i);
|
||||
}
|
||||
// Display header
|
||||
let mut r = writeln!(f, "{:^3} {:^7} | {:^8} {:^8} {:^8} {:^8} | {:^8} {:^8} {:^8} {:^8} | {:^8} {:^8} {:^8} {:^8}",
|
||||
"pat", "offset",
|
||||
"SF Ac H", "SF Ac HR", "SF Pr H", "SF Pr HR",
|
||||
"SR Ac H", "SR Ac HR", "SR Pr H", "SR Pr HR",
|
||||
"FF Ac H", "FF Ac HR", "FF Pr H", "FF Pr HR");
|
||||
match r {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..PAGE_CACHELINE_LEN {
|
||||
let index = indices[i];
|
||||
|
||||
let (pat, sf_ac_h, sf_ac_hr, sr_ac_h, sr_ac_hr, ff_ac_h, ff_ac_hr) = match index {
|
||||
None => (
|
||||
String::from(""),
|
||||
String::from(""),
|
||||
String::from(""),
|
||||
String::from(""),
|
||||
String::from(""),
|
||||
String::from(""),
|
||||
String::from(""),
|
||||
),
|
||||
Some(index) => {
|
||||
let pat = format!("{:3}", index);
|
||||
let sf_ac: u32 = self
|
||||
.single_probe_results
|
||||
.iter()
|
||||
.map(|d| d.flush.pattern_result[index])
|
||||
.sum();
|
||||
let sf_ac_h = format!("{:8}", sf_ac);
|
||||
let sf_ac_hr = format!("{:8}", sf_ac as f32 / divider);
|
||||
|
||||
let sr_ac: u32 = self
|
||||
.single_probe_results
|
||||
.iter()
|
||||
.map(|d| d.load.pattern_result[index])
|
||||
.sum();
|
||||
let sr_ac_h = format!("{:8}", sr_ac);
|
||||
let sr_ac_hr = format!("{:8}", sr_ac as f32 / divider);
|
||||
|
||||
let ff_ac = self.full_flush_results.pattern_result[index];
|
||||
let ff_ac_h = format!("{:8}", ff_ac);
|
||||
let ff_ac_hr = format!("{:8}", ff_ac as f32 / self.num_iteration as f32);
|
||||
(pat, sf_ac_h, sf_ac_hr, sr_ac_h, sr_ac_hr, ff_ac_h, ff_ac_hr)
|
||||
}
|
||||
};
|
||||
|
||||
let sf_pr = self.single_probe_results[i].flush.probe_result;
|
||||
let sf_pr_h = format!("{:8}", sf_pr);
|
||||
let sf_pr_hr = format!("{:8}", sf_pr as f32 / self.num_iteration as f32);
|
||||
|
||||
let sr_pr = self.single_probe_results[i].load.probe_result;
|
||||
let sr_pr_h = format!("{:8}", sr_pr);
|
||||
let sr_pr_hr = format!("{:8}", sr_pr as f32 / self.num_iteration as f32);
|
||||
|
||||
let ff_pr = self.full_flush_results.probe_result[i];
|
||||
let ff_pr_h = format!("{:8}", ff_pr);
|
||||
let ff_pr_hr = format!("{:8}", ff_pr as f32 / self.num_iteration as f32);
|
||||
|
||||
r = writeln!(f, "{:>3} {:>7} | {:>8} {:^8} {:>8} {:^8} | {:>8} {:^8} {:>8} {:^8} | {:>8} {:^8} {:>8} {:^8}",
|
||||
pat, i,
|
||||
sf_ac_h, sf_ac_hr, sf_pr_h, sf_pr_hr,
|
||||
sr_ac_h, sr_ac_hr, sr_pr_h, sr_pr_hr,
|
||||
ff_ac_h, ff_ac_hr, ff_pr_h, ff_pr_hr);
|
||||
match r {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
// display lines
|
||||
}
|
||||
write!(f, "Num_iteration: {}", self.num_iteration)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(unsafe_block_in_unsafe_fn)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
use basic_timing_cache_channel::TopologyAwareError;
|
||||
use cache_side_channel::CacheStatus::Hit;
|
||||
@ -44,7 +43,7 @@ fn execute_pattern(
|
||||
unsafe { maccess(pointer) };
|
||||
}
|
||||
|
||||
let mut measures = unsafe { channel.test(page_handles, true) };
|
||||
let measures = unsafe { channel.test(page_handles, true) };
|
||||
|
||||
let mut res = vec![false; PAGE_CACHELINE_LEN];
|
||||
|
||||
@ -65,12 +64,13 @@ fn execute_pattern_probe1(
|
||||
unsafe { maccess(pointer) };
|
||||
}
|
||||
|
||||
let mut measure = unsafe { channel.test_single(&mut page_handles[probe_offset], true) };
|
||||
let measure = unsafe { channel.test_single(&mut page_handles[probe_offset], true) };
|
||||
|
||||
measure.unwrap() == Hit
|
||||
}
|
||||
|
||||
fn main() {
|
||||
/*
|
||||
let mut vec = Vec::new();
|
||||
let mut handles = Vec::new();
|
||||
let (mut channel, cpuset, core) = FlushAndFlush::new_any_single_core().unwrap();
|
||||
@ -121,7 +121,7 @@ fn main() {
|
||||
let mut probe_all_result_first = [0; PAGE_CACHELINE_LEN];
|
||||
for _ in 0..NUM_ITERATION {
|
||||
let page_index = page_indexes.next().unwrap();
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) };
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) }.unwrap();
|
||||
let res = execute_pattern(&mut channel, &mut handles_mutref[page_index], &pattern);
|
||||
for j in 0..PAGE_CACHELINE_LEN {
|
||||
if res[j] {
|
||||
@ -133,7 +133,7 @@ fn main() {
|
||||
for i in 0..PAGE_CACHELINE_LEN {
|
||||
for _ in 0..NUM_ITERATION {
|
||||
let page_index = page_indexes.next().unwrap();
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) };
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) }.unwrap();
|
||||
let res =
|
||||
execute_pattern_probe1(&mut channel, &mut handles_mutref[page_index], &pattern, i);
|
||||
if res {
|
||||
@ -144,7 +144,7 @@ fn main() {
|
||||
let mut probe_all_result = [0; PAGE_CACHELINE_LEN];
|
||||
for _ in 0..NUM_ITERATION {
|
||||
let page_index = page_indexes.next().unwrap();
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) };
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) }.unwrap();
|
||||
let res = execute_pattern(&mut channel, &mut handles_mutref[page_index], &pattern);
|
||||
for j in 0..PAGE_CACHELINE_LEN {
|
||||
if res[j] {
|
||||
@ -165,7 +165,7 @@ fn main() {
|
||||
let mut probe_all_result_first = [0; PAGE_CACHELINE_LEN];
|
||||
for _ in 0..NUM_ITERATION {
|
||||
let page_index = page_indexes.next().unwrap();
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) };
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) }.unwrap();
|
||||
let res = execute_pattern(&mut channel, &mut handles_mutref[page_index], &pattern);
|
||||
for j in 0..PAGE_CACHELINE_LEN {
|
||||
if res[j] {
|
||||
@ -177,7 +177,7 @@ fn main() {
|
||||
for i in 0..PAGE_CACHELINE_LEN {
|
||||
for _ in 0..NUM_ITERATION {
|
||||
let page_index = page_indexes.next().unwrap();
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) };
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) }.unwrap();
|
||||
let res =
|
||||
execute_pattern_probe1(&mut channel, &mut handles_mutref[page_index], &pattern, i);
|
||||
if res {
|
||||
@ -188,15 +188,24 @@ fn main() {
|
||||
let mut probe_all_result = [0; PAGE_CACHELINE_LEN];
|
||||
for _ in 0..NUM_ITERATION {
|
||||
let page_index = page_indexes.next().unwrap();
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) };
|
||||
unsafe { channel.prepare(&mut handles_mutref[page_index]) }.unwrap();
|
||||
let res = execute_pattern(&mut channel, &mut handles_mutref[page_index], &pattern);
|
||||
for j in 0..PAGE_CACHELINE_LEN {
|
||||
if res[j] {
|
||||
probe_all_result[j] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
let pattern = generate_pattern(0, 3, 12).unwrap();
|
||||
let mut new_prober = Prober::new(63).unwrap();
|
||||
let result = new_prober.full_page_probe(pattern.clone(), NUM_ITERATION as u32, 100);
|
||||
println!("{}", result);
|
||||
println!("{:#?}", result);
|
||||
|
||||
let result2 = new_prober.full_page_probe(pattern, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result2);
|
||||
/*
|
||||
for i in 0..PAGE_CACHELINE_LEN {
|
||||
println!(
|
||||
"{:2} {:4} {:4} {:4}",
|
||||
@ -204,9 +213,9 @@ fn main() {
|
||||
);
|
||||
}
|
||||
|
||||
println!("Hello, world!");
|
||||
println!("{:?}", generate_pattern(0, 5, 1));
|
||||
println!("{:?}", generate_pattern(5, 0, 1));
|
||||
println!("{:?}", generate_pattern(1, 5, 5));
|
||||
println!("{:?}", generate_pattern(0, 16, 16));
|
||||
*/
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user