General updates
This commit is contained in:
parent
c734b5ce53
commit
559a4ecdf8
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -110,9 +110,11 @@ name = "cache_utils"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"atomic",
|
||||
"bitvec",
|
||||
"cpuid",
|
||||
"hashbrown",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"nix",
|
||||
"polling_serial",
|
||||
@ -376,6 +378,7 @@ dependencies = [
|
||||
"cache_utils",
|
||||
"flush_flush",
|
||||
"flush_reload",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"nix",
|
||||
"rand",
|
||||
|
@ -16,3 +16,4 @@ nix = "0.20.0"
|
||||
rand = "0.8.3"
|
||||
lazy_static = "1.4.0"
|
||||
bitvec = "0.22.3"
|
||||
itertools = "0.10.0"
|
||||
|
9
prefetcher_reverse/MSR1A4.txt
Normal file
9
prefetcher_reverse/MSR1A4.txt
Normal file
@ -0,0 +1,9 @@
|
||||
On Nehalem :
|
||||
Bit 1 L2 Prefetcher
|
||||
Bit 2 L2 Adjacent Cache line
|
||||
Bit 3 L1 DCU next cache line
|
||||
Bit 4 L1 IP based prefetcher
|
||||
|
||||
This is confirmed for Sandy Bridge in Table 2-20, which is supported by most processors of later generation (up to KabyLake at least)
|
||||
|
||||
For strides, consider f, e and 7
|
8
prefetcher_reverse/run-msr-eap.sh
Executable file
8
prefetcher_reverse/run-msr-eap.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
PREFETCH_MSR=$1
|
||||
sudo wrmsr -a 0x1a4 $PREFETCH_MSR
|
||||
sudo echo wrmsr -a 0x1a4 $PREFETCH_MSR
|
||||
sudo rdmsr -a 0x1a4
|
||||
cargo run --release --bin exhaustive_access_pattern > eap-with-${PREFETCH_MSR}-prefetcher.log
|
||||
sudo rdmsr -a 0x1a4
|
||||
|
165
prefetcher_reverse/src/bin/exhaustive_access_pattern.rs
Normal file
165
prefetcher_reverse/src/bin/exhaustive_access_pattern.rs
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
Objective : run an exploration of patterns of a length given as an arg and test all the possible ones,
|
||||
Then proceed with some analysis.
|
||||
|
||||
Probably will use library functions for a lot of it
|
||||
(Auto pattern generation belongs in lib.rs, the analysis part may be a little bit more subtle)
|
||||
|
||||
Output, detailed CSV, and well chosen slices + summaries ?
|
||||
|
||||
Alternatively, limit to 3 accesses ?
|
||||
|
||||
*/
|
||||
|
||||
use cache_utils::ip_tool::{Function, TIMED_MACCESS};
|
||||
use itertools::Itertools;
|
||||
use nix::sched::sched_yield;
|
||||
use prefetcher_reverse::{
|
||||
pattern_helper, FullPageDualProbeResults, PatternAccess, Prober, PAGE_CACHELINE_LEN,
|
||||
};
|
||||
|
||||
pub const NUM_ITERATION: u32 = 1 << 10;
|
||||
pub const WARMUP: u32 = 100;
|
||||
|
||||
struct Params {
|
||||
limit: usize,
|
||||
same_ip: bool,
|
||||
unique_ip: bool,
|
||||
}
|
||||
|
||||
fn print_tagged_csv(tag: &str, results: Vec<FullPageDualProbeResults>, len: usize) {
|
||||
// Print Header,
|
||||
println!("{}Functions:i,Addr", tag);
|
||||
if !results.is_empty() {
|
||||
let first = &results[0];
|
||||
for (i, p) in first.pattern.iter().enumerate() {
|
||||
println!("{}Functions:{},{:p}", tag, i, p.function.ip)
|
||||
}
|
||||
}
|
||||
println!(
|
||||
"{}:{}ProbeAddr,Probe_SF_H,Probe_SF_HR,Probe_SR_H,Probe_SR_HR,Probe_FF_H,Probe_FF_HR",
|
||||
tag,
|
||||
(0..len)
|
||||
.map(|i| {
|
||||
format!(
|
||||
"Offset_{i},\
|
||||
Offset_{i}_SF_H,Offset_{i}_SF_HR,\
|
||||
Offset_{i}_SR_H,Offset_{i}_SR_HR,\
|
||||
Offset_{i}_FF_H,Offset_{i}_FF_HR,",
|
||||
i = i
|
||||
)
|
||||
})
|
||||
.format(""),
|
||||
);
|
||||
// Print each line,
|
||||
// TODO : double check with the impl in lib.rs how to extract the various piece of info.
|
||||
for res in results {
|
||||
assert_eq!(res.pattern.len(), len);
|
||||
|
||||
for probe_addr in 0..PAGE_CACHELINE_LEN {
|
||||
let sf_h = res.single_probe_results[probe_addr].flush.probe_result;
|
||||
let sr_h = res.single_probe_results[probe_addr].load.probe_result;
|
||||
let ff_h = res.full_flush_results.probe_result[probe_addr];
|
||||
println!(
|
||||
"{}:{}{},{},{},{},{},{},{}",
|
||||
tag,
|
||||
(0..len)
|
||||
.map(|i| {
|
||||
let sf_h = res.single_probe_results[probe_addr].flush.pattern_result[i];
|
||||
let sf_hr = sf_h as f32 / res.num_iteration as f32;
|
||||
let sr_h = res.single_probe_results[probe_addr].load.pattern_result[i];
|
||||
let sr_hr = sr_h as f32 / res.num_iteration as f32;
|
||||
let ff_h = res.full_flush_results.pattern_result[i];
|
||||
let ff_hr = ff_h as f32 / res.num_iteration as f32;
|
||||
format!(
|
||||
"{},{},{},{},{},{},{},",
|
||||
res.pattern[i].offset, sf_h, sf_hr, sr_h, sr_hr, ff_h, ff_hr
|
||||
)
|
||||
})
|
||||
.format(""),
|
||||
probe_addr,
|
||||
sf_h,
|
||||
sf_h as f32 / res.num_iteration as f32,
|
||||
sr_h,
|
||||
sr_h as f32 / res.num_iteration as f32,
|
||||
ff_h,
|
||||
ff_h as f32 / res.num_iteration as f32
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn exp(
|
||||
i: usize,
|
||||
patterns: &Vec<Vec<usize>>,
|
||||
same_ip: bool,
|
||||
unique_ip: bool,
|
||||
prober: &mut Prober<1>,
|
||||
) {
|
||||
if same_ip {
|
||||
let single_reload = Function::try_new(1, 0, TIMED_MACCESS).unwrap();
|
||||
let mut results = Vec::new();
|
||||
for pattern in patterns {
|
||||
eprintln!("Single IP pattern: {:?}", pattern);
|
||||
let single_ip_pattern = pattern_helper(pattern, &single_reload);
|
||||
let result = prober.full_page_probe(single_ip_pattern, NUM_ITERATION, WARMUP);
|
||||
results.push(result);
|
||||
sched_yield().unwrap();
|
||||
}
|
||||
print_tagged_csv(&format!("SingleIP{}", i), results, i);
|
||||
// generate the vec with a single IP
|
||||
}
|
||||
if unique_ip {
|
||||
let mut functions = Vec::new();
|
||||
let rounded_i = i.next_power_of_two();
|
||||
for j in 0..i {
|
||||
functions.push(Function::try_new(rounded_i, j, TIMED_MACCESS).unwrap());
|
||||
}
|
||||
let mut results = Vec::new();
|
||||
for pattern in patterns {
|
||||
eprintln!("Unique IP pattern: {:?}", pattern);
|
||||
|
||||
let unique_ip_pattern = pattern
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &offset)| PatternAccess {
|
||||
function: &functions[i],
|
||||
offset,
|
||||
})
|
||||
.collect();
|
||||
let result = prober.full_page_probe(unique_ip_pattern, NUM_ITERATION, WARMUP);
|
||||
results.push(result);
|
||||
sched_yield().unwrap();
|
||||
}
|
||||
print_tagged_csv(&format!("UniqueIPs{}", i), results, i);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// TODO Argument parsing
|
||||
let args = Params {
|
||||
limit: 2,
|
||||
same_ip: true,
|
||||
unique_ip: true,
|
||||
};
|
||||
|
||||
let mut prober = Prober::<1>::new(63).unwrap();
|
||||
|
||||
let mut patterns: Vec<Vec<usize>> = Vec::new();
|
||||
patterns.push(Vec::new());
|
||||
|
||||
exp(0, &patterns, args.same_ip, args.unique_ip, &mut prober);
|
||||
|
||||
for i in 0..args.limit {
|
||||
let mut new_patterns = Vec::new();
|
||||
for pattern in patterns {
|
||||
for i in 0..PAGE_CACHELINE_LEN {
|
||||
let mut np = pattern.clone();
|
||||
np.push(i);
|
||||
new_patterns.push(np);
|
||||
}
|
||||
}
|
||||
patterns = new_patterns;
|
||||
exp(i + 1, &patterns, args.same_ip, args.unique_ip, &mut prober);
|
||||
}
|
||||
}
|
183
prefetcher_reverse/src/bin/extra_access_pattern.rs
Normal file
183
prefetcher_reverse/src/bin/extra_access_pattern.rs
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
Objective : run an exploration of patterns of a length given as an arg and test all the possible ones,
|
||||
Then proceed with some analysis.
|
||||
|
||||
Probably will use library functions for a lot of it
|
||||
(Auto pattern generation belongs in lib.rs, the analysis part may be a little bit more subtle)
|
||||
|
||||
Output, detailed CSV, and well chosen slices + summaries ?
|
||||
|
||||
Alternatively, limit to 3 accesses ?
|
||||
|
||||
*/
|
||||
|
||||
use cache_utils::ip_tool::{Function, TIMED_MACCESS};
|
||||
use itertools::Itertools;
|
||||
use nix::sched::sched_yield;
|
||||
use prefetcher_reverse::{
|
||||
pattern_helper, FullPageDualProbeResults, PatternAccess, Prober, PAGE_CACHELINE_LEN,
|
||||
};
|
||||
|
||||
pub const NUM_ITERATION: u32 = 1 << 10;
|
||||
pub const WARMUP: u32 = 100;
|
||||
|
||||
struct Params {
|
||||
limit: usize,
|
||||
same_ip: bool,
|
||||
unique_ip: bool,
|
||||
}
|
||||
|
||||
fn print_tagged_csv(tag: &str, results: Vec<FullPageDualProbeResults>, len: usize) {
|
||||
// Print Header,
|
||||
println!("{}Functions:i,Addr", tag);
|
||||
if !results.is_empty() {
|
||||
let first = &results[0];
|
||||
for (i, p) in first.pattern.iter().enumerate() {
|
||||
println!("{}Functions:{},{:p}", tag, i, p.function.ip)
|
||||
}
|
||||
}
|
||||
println!(
|
||||
"{}:{}ProbeAddr,Probe_SF_H,Probe_SF_HR,Probe_SR_H,Probe_SR_HR,Probe_FF_H,Probe_FF_HR",
|
||||
tag,
|
||||
(0..len)
|
||||
.map(|i| {
|
||||
format!(
|
||||
"Offset_{i},\
|
||||
Offset_{i}_SF_H,Offset_{i}_SF_HR,\
|
||||
Offset_{i}_SR_H,Offset_{i}_SR_HR,\
|
||||
Offset_{i}_FF_H,Offset_{i}_FF_HR,",
|
||||
i = i
|
||||
)
|
||||
})
|
||||
.format(""),
|
||||
);
|
||||
// Print each line,
|
||||
// TODO : double check with the impl in lib.rs how to extract the various piece of info.
|
||||
for res in results {
|
||||
assert_eq!(res.pattern.len(), len);
|
||||
|
||||
for probe_addr in 0..PAGE_CACHELINE_LEN {
|
||||
let sf_h = res.single_probe_results[probe_addr].flush.probe_result;
|
||||
let sr_h = res.single_probe_results[probe_addr].load.probe_result;
|
||||
let ff_h = res.full_flush_results.probe_result[probe_addr];
|
||||
println!(
|
||||
"{}:{}{},{},{},{},{},{},{}",
|
||||
tag,
|
||||
(0..len)
|
||||
.map(|i| {
|
||||
let sf_h = res.single_probe_results[probe_addr].flush.pattern_result[i];
|
||||
let sf_hr = sf_h as f32 / res.num_iteration as f32;
|
||||
let sr_h = res.single_probe_results[probe_addr].load.pattern_result[i];
|
||||
let sr_hr = sr_h as f32 / res.num_iteration as f32;
|
||||
let ff_h = res.full_flush_results.pattern_result[i];
|
||||
let ff_hr = ff_h as f32 / res.num_iteration as f32;
|
||||
format!(
|
||||
"{},{},{},{},{},{},{},",
|
||||
res.pattern[i].offset, sf_h, sf_hr, sr_h, sr_hr, ff_h, ff_hr
|
||||
)
|
||||
})
|
||||
.format(""),
|
||||
probe_addr,
|
||||
sf_h,
|
||||
sf_h as f32 / res.num_iteration as f32,
|
||||
sr_h,
|
||||
sr_h as f32 / res.num_iteration as f32,
|
||||
ff_h,
|
||||
ff_h as f32 / res.num_iteration as f32
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn exp(
|
||||
i: usize,
|
||||
patterns: &Vec<Vec<usize>>,
|
||||
same_ip: bool,
|
||||
unique_ip: bool,
|
||||
prober: &mut Prober<1>,
|
||||
) {
|
||||
if same_ip {
|
||||
let single_reload = Function::try_new(1, 0, TIMED_MACCESS).unwrap();
|
||||
let mut results = Vec::new();
|
||||
for pattern in patterns {
|
||||
eprintln!("Single IP pattern: {:?}", pattern);
|
||||
let single_ip_pattern = pattern_helper(pattern, &single_reload);
|
||||
let result = prober.full_page_probe(single_ip_pattern, NUM_ITERATION, WARMUP);
|
||||
results.push(result);
|
||||
sched_yield().unwrap();
|
||||
}
|
||||
print_tagged_csv(&format!("SingleIP{}", i), results, i);
|
||||
// generate the vec with a single IP
|
||||
}
|
||||
if unique_ip {
|
||||
let mut functions = Vec::new();
|
||||
let rounded_i = i.next_power_of_two();
|
||||
for j in 0..i {
|
||||
functions.push(Function::try_new(rounded_i, j, TIMED_MACCESS).unwrap());
|
||||
}
|
||||
let mut results = Vec::new();
|
||||
for pattern in patterns {
|
||||
eprintln!("Unique IP pattern: {:?}", pattern);
|
||||
|
||||
let unique_ip_pattern = pattern
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &offset)| PatternAccess {
|
||||
function: &functions[i],
|
||||
offset,
|
||||
})
|
||||
.collect();
|
||||
let result = prober.full_page_probe(unique_ip_pattern, NUM_ITERATION, WARMUP);
|
||||
results.push(result);
|
||||
sched_yield().unwrap();
|
||||
}
|
||||
print_tagged_csv(&format!("UniqueIPs{}", i), results, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO change access patterns
|
||||
- We want patterns for i,j in [0,64]^2
|
||||
A (i,i+k,j)
|
||||
B (i,i-k,j)
|
||||
C (i,j,j+k)
|
||||
D (i,j,j-k)
|
||||
|
||||
with k in 1,2,3,8, plus possibly others.
|
||||
4 access patterns will probably come in later
|
||||
|
||||
In addition consider base + stride + len patterns, with a well chosen set of length, strides and bases
|
||||
len to be considered 2,3,4
|
||||
Identifiers :
|
||||
E 2
|
||||
F 3
|
||||
G 4
|
||||
*/
|
||||
|
||||
fn main() {
|
||||
// TODO Argument parsing
|
||||
let args = Params {
|
||||
limit: 2,
|
||||
same_ip: true,
|
||||
unique_ip: true,
|
||||
};
|
||||
|
||||
let mut prober = Prober::<1>::new(63).unwrap();
|
||||
|
||||
let mut patterns: Vec<Vec<usize>> = Vec::new();
|
||||
patterns.push(Vec::new());
|
||||
|
||||
exp(0, &patterns, args.same_ip, args.unique_ip, &mut prober);
|
||||
|
||||
for i in 0..args.limit {
|
||||
let mut new_patterns = Vec::new();
|
||||
for pattern in patterns {
|
||||
for i in 0..PAGE_CACHELINE_LEN {
|
||||
let mut np = pattern.clone();
|
||||
np.push(i);
|
||||
new_patterns.push(np);
|
||||
}
|
||||
}
|
||||
patterns = new_patterns;
|
||||
exp(i + 1, &patterns, args.same_ip, args.unique_ip, &mut prober);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use prefetcher_reverse::ip_tool::tmp_test;
|
||||
use cache_utils::ip_tool::tmp_test;
|
||||
|
||||
fn main() {
|
||||
tmp_test();
|
||||
|
@ -1,4 +1,4 @@
|
||||
use prefetcher_reverse::ip_tool::{Function, TIMED_MACCESS};
|
||||
use cache_utils::ip_tool::{Function, TIMED_MACCESS};
|
||||
use prefetcher_reverse::{pattern_helper, Prober, PAGE_CACHELINE_LEN};
|
||||
|
||||
pub const NUM_ITERATION: usize = 1 << 10;
|
||||
@ -7,7 +7,7 @@ fn exp(delay: u64, reload: &Function) {
|
||||
let mut prober = Prober::<2>::new(63).unwrap();
|
||||
prober.set_delay(delay);
|
||||
let pattern = (0usize..(PAGE_CACHELINE_LEN * 2usize)).collect::<Vec<usize>>();
|
||||
let p = pattern_helper(pattern, reload);
|
||||
let p = pattern_helper(&pattern, reload);
|
||||
|
||||
let result = prober.full_page_probe(p, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result);
|
||||
|
@ -5,12 +5,12 @@ use cache_side_channel::{
|
||||
set_affinity, ChannelHandle, CoreSpec, MultipleAddrCacheSideChannel, SingleAddrCacheSideChannel,
|
||||
};
|
||||
use cache_utils::calibration::PAGE_LEN;
|
||||
use cache_utils::ip_tool::{Function, TIMED_MACCESS};
|
||||
use cache_utils::maccess;
|
||||
use cache_utils::mmap;
|
||||
use cache_utils::mmap::MMappedMemory;
|
||||
use flush_flush::{FFHandle, FFPrimitives, FlushAndFlush};
|
||||
use nix::Error;
|
||||
use prefetcher_reverse::ip_tool::{Function, TIMED_MACCESS};
|
||||
use prefetcher_reverse::{
|
||||
pattern_helper, reference_patterns, Prober, CACHE_LINE_LEN, PAGE_CACHELINE_LEN,
|
||||
};
|
||||
@ -23,7 +23,7 @@ pub const NUM_PAGES: usize = 256;
|
||||
|
||||
fn exp(delay: u64, reload: &Function) {
|
||||
for (name, pattern) in reference_patterns() {
|
||||
let p = pattern_helper(pattern, reload);
|
||||
let p = pattern_helper(&pattern, reload);
|
||||
let mut prober = Prober::<1>::new(63).unwrap();
|
||||
|
||||
println!("{}", name);
|
||||
|
@ -1,5 +1,5 @@
|
||||
use cache_utils::ip_tool::{Function, TIMED_MACCESS};
|
||||
use cache_utils::{flush, maccess};
|
||||
use prefetcher_reverse::ip_tool::{Function, TIMED_MACCESS};
|
||||
use prefetcher_reverse::{pattern_helper, Prober, PAGE_CACHELINE_LEN};
|
||||
use std::arch::x86_64 as arch_x86;
|
||||
|
||||
@ -44,7 +44,7 @@ fn exp(stride: usize, num_steps: i32, delay: u64, reload: &Function) {
|
||||
stride * num_steps as usize
|
||||
};
|
||||
let pattern = (2usize..limit).step_by(stride).collect::<Vec<_>>();
|
||||
let p = pattern_helper(pattern, reload);
|
||||
let p = pattern_helper(&pattern, reload);
|
||||
|
||||
let pl2 = Function {
|
||||
fun: prefetch_l2,
|
||||
@ -67,13 +67,13 @@ fn exp(stride: usize, num_steps: i32, delay: u64, reload: &Function) {
|
||||
size: 0,
|
||||
};
|
||||
|
||||
let mut pattern_pl2 = pattern_helper((0..(2 * PAGE_CACHELINE_LEN)).collect(), &pl2);
|
||||
let mut pattern_pl2 = pattern_helper(&(0..(2 * PAGE_CACHELINE_LEN)).collect(), &pl2);
|
||||
pattern_pl2.extend(p.iter().cloned());
|
||||
|
||||
let mut pattern_pl3 = pattern_helper((0..(2 * PAGE_CACHELINE_LEN)).collect(), &pl3);
|
||||
let mut pattern_pl3 = pattern_helper(&(0..(2 * PAGE_CACHELINE_LEN)).collect(), &pl3);
|
||||
pattern_pl3.extend(p.iter().cloned());
|
||||
|
||||
let mut pattern_pl1 = pattern_helper((0..(2 * PAGE_CACHELINE_LEN)).collect(), &pl1);
|
||||
let mut pattern_pl1 = pattern_helper(&(0..(2 * PAGE_CACHELINE_LEN)).collect(), &pl1);
|
||||
pattern_pl1.extend(p.iter().cloned());
|
||||
|
||||
println!("With no sw prefetch");
|
||||
|
@ -1,4 +1,4 @@
|
||||
use prefetcher_reverse::ip_tool::{Function, TIMED_MACCESS};
|
||||
use cache_utils::ip_tool::{Function, TIMED_MACCESS};
|
||||
use prefetcher_reverse::{pattern_helper, Prober, PAGE_CACHELINE_LEN};
|
||||
|
||||
pub const NUM_ITERATION: usize = 1 << 10;
|
||||
@ -12,7 +12,7 @@ fn exp(stride: usize, num_steps: i32, delay: u64, reload: &Function) {
|
||||
stride * num_steps as usize
|
||||
};
|
||||
let pattern = (2usize..limit).step_by(stride).collect::<Vec<_>>();
|
||||
let p = pattern_helper(pattern, reload);
|
||||
let p = pattern_helper(&pattern, reload);
|
||||
|
||||
let result = prober.full_page_probe(p, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result);
|
||||
|
@ -1,8 +1,14 @@
|
||||
#![feature(global_asm)]
|
||||
#![feature(linked_list_cursors)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use crate::Probe::{Flush, FullFlush, Load};
|
||||
use std::fmt::{Display, Error, Formatter};
|
||||
use std::iter::{Cycle, Peekable};
|
||||
use std::ops::Range;
|
||||
use std::{thread, time};
|
||||
|
||||
use nix::sys::stat::stat;
|
||||
use rand::seq::SliceRandom;
|
||||
|
||||
use basic_timing_cache_channel::{
|
||||
CalibrationStrategy, TopologyAwareError, TopologyAwareTimingChannel,
|
||||
};
|
||||
@ -12,21 +18,14 @@ use cache_side_channel::{
|
||||
SingleAddrCacheSideChannel,
|
||||
};
|
||||
use cache_utils::calibration::{only_reload, Threshold, PAGE_LEN};
|
||||
use cache_utils::ip_tool::Function;
|
||||
use cache_utils::mmap::MMappedMemory;
|
||||
use cache_utils::rdtsc_nofence;
|
||||
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;
|
||||
use std::{thread, time};
|
||||
|
||||
pub mod ip_tool;
|
||||
|
||||
use ip_tool::Function;
|
||||
use crate::Probe::{Flush, FullFlush, Load};
|
||||
|
||||
// NB these may need to be changed / dynamically measured.
|
||||
pub const CACHE_LINE_LEN: usize = 64;
|
||||
@ -37,12 +36,12 @@ pub const CALIBRATION_STRAT: CalibrationStrategy = CalibrationStrategy::ASVP;
|
||||
pub struct Prober<const GS: usize> {
|
||||
pages: Vec<MMappedMemory<u8>>,
|
||||
ff_handles: Vec<Vec<FFHandle>>,
|
||||
//fr_handles: Vec<Vec<FRHandle>>,
|
||||
fr_handles: Vec<Vec<NFRHandle>>,
|
||||
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,
|
||||
fr_channel: FlushAndReload,
|
||||
//fr_channel: NaiveFlushAndReload,
|
||||
delay: u64,
|
||||
}
|
||||
|
||||
@ -120,7 +119,7 @@ pub struct FullPageDualProbeResults<'a> {
|
||||
pub full_flush_results: DPRItem<FullPR>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SingleProbeResult {
|
||||
pub probe_offset: usize,
|
||||
pub pattern_result: Vec<u64>,
|
||||
@ -177,16 +176,16 @@ impl<const GS: usize> Prober<GS> {
|
||||
Ok(old) => old,
|
||||
Err(nixerr) => return Err(ProberError::Nix(nixerr)),
|
||||
};
|
||||
let mut fr_channel = NaiveFlushAndReload::new(Threshold {
|
||||
/*let mut fr_channel = NaiveFlushAndReload::new(Threshold {
|
||||
bucket_index: 315,
|
||||
miss_faster_than_hit: false,
|
||||
});
|
||||
/*let mut fr_channel = match FlushAndReload::new(core, core, CALIBRATION_STRAT) {
|
||||
});*/
|
||||
let mut fr_channel = match FlushAndReload::new(core, core, CALIBRATION_STRAT) {
|
||||
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 * GS, false, false, |j| {
|
||||
@ -246,7 +245,9 @@ impl<const GS: usize> Prober<GS> {
|
||||
self.page_indexes.next();
|
||||
let page_index = *self.page_indexes.peek().unwrap();
|
||||
|
||||
let mut ff_handles = self.ff_handles[page_index].iter_mut().collect();
|
||||
let mut ff_handles = self.ff_handles[page_index]
|
||||
.iter_mut() /*.rev()*/
|
||||
.collect();
|
||||
|
||||
unsafe { self.ff_channel.prepare(&mut ff_handles) };
|
||||
|
||||
@ -293,7 +294,7 @@ impl<const GS: usize> Prober<GS> {
|
||||
if let ProbeOutput::Full(vstatus) = probe_out {
|
||||
for (i, status) in vstatus.iter().enumerate() {
|
||||
if status.1 == Hit {
|
||||
v[i] += 1;
|
||||
v[/*63 -*/ i] += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -347,16 +348,26 @@ impl<const GS: usize> Prober<GS> {
|
||||
pattern: pattern.pattern.clone(),
|
||||
probe_type,
|
||||
num_iteration,
|
||||
results: vec![],
|
||||
results: vec![
|
||||
SingleProbeResult {
|
||||
probe_offset: 0,
|
||||
pattern_result: vec![],
|
||||
probe_result: 0
|
||||
};
|
||||
64
|
||||
],
|
||||
};
|
||||
for offset in 0..(PAGE_CACHELINE_LEN * GS) {
|
||||
for offset in (0..(PAGE_CACHELINE_LEN * GS))
|
||||
/*.rev()*/
|
||||
{
|
||||
// Reversed FIXME
|
||||
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 {
|
||||
result.results[offset] = SingleProbeResult {
|
||||
probe_offset: offset,
|
||||
pattern_result: r.pattern_result,
|
||||
probe_result: match r.probe_result {
|
||||
@ -364,7 +375,7 @@ impl<const GS: usize> Prober<GS> {
|
||||
ProbeResult::Flush(r) => r,
|
||||
ProbeResult::FullFlush(r) => r[offset],
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
result
|
||||
}
|
||||
@ -537,12 +548,12 @@ pub fn reference_patterns() -> [(&'static str, Vec<usize>); 9] {
|
||||
]
|
||||
}
|
||||
|
||||
pub fn pattern_helper<'a>(offsets: Vec<usize>, function: &'a Function) -> Vec<PatternAccess<'a>> {
|
||||
pub fn pattern_helper<'a>(offsets: &Vec<usize>, function: &'a Function) -> Vec<PatternAccess<'a>> {
|
||||
offsets
|
||||
.into_iter()
|
||||
.map(|i| PatternAccess {
|
||||
function,
|
||||
offset: i,
|
||||
offset: *i,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -5,12 +5,12 @@ use cache_side_channel::{
|
||||
set_affinity, ChannelHandle, CoreSpec, MultipleAddrCacheSideChannel, SingleAddrCacheSideChannel,
|
||||
};
|
||||
use cache_utils::calibration::PAGE_LEN;
|
||||
use cache_utils::ip_tool::{Function, TIMED_MACCESS};
|
||||
use cache_utils::maccess;
|
||||
use cache_utils::mmap;
|
||||
use cache_utils::mmap::MMappedMemory;
|
||||
use flush_flush::{FFHandle, FFPrimitives, FlushAndFlush};
|
||||
use nix::Error;
|
||||
use prefetcher_reverse::ip_tool::{Function, TIMED_MACCESS};
|
||||
use prefetcher_reverse::{
|
||||
pattern_helper, PatternAccess, Prober, CACHE_LINE_LEN, PAGE_CACHELINE_LEN,
|
||||
};
|
||||
@ -201,8 +201,8 @@ fn main() {
|
||||
|
||||
let reload = Function::try_new(1, 0, TIMED_MACCESS).unwrap();
|
||||
|
||||
let pattern = pattern_helper(generate_pattern(0, 3, 12).unwrap(), &reload);
|
||||
let pattern4 = pattern_helper(generate_pattern(0, 4, 12).unwrap(), &reload);
|
||||
let pattern = pattern_helper(&generate_pattern(0, 3, 12).unwrap(), &reload);
|
||||
let pattern4 = pattern_helper(&generate_pattern(0, 4, 12).unwrap(), &reload);
|
||||
let mut new_prober = Prober::<1>::new(63).unwrap();
|
||||
let result = new_prober.full_page_probe(pattern.clone(), NUM_ITERATION as u32, 100);
|
||||
println!("{}", result);
|
||||
@ -212,27 +212,27 @@ fn main() {
|
||||
println!("{}", result2);
|
||||
let result4 = new_prober.full_page_probe(pattern4, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result4);
|
||||
let pattern5 = pattern_helper(generate_pattern(0, 5, 8).unwrap(), &reload);
|
||||
let pattern5 = pattern_helper(&generate_pattern(0, 5, 8).unwrap(), &reload);
|
||||
let result5 = new_prober.full_page_probe(pattern5, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result5);
|
||||
|
||||
let pattern5 = pattern_helper(generate_pattern(0, 5, 4).unwrap(), &reload);
|
||||
let pattern5 = pattern_helper(&generate_pattern(0, 5, 4).unwrap(), &reload);
|
||||
let result5 = new_prober.full_page_probe(pattern5, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result5);
|
||||
|
||||
let pattern = pattern_helper(generate_pattern(0, 10, 4).unwrap(), &reload);
|
||||
let pattern = pattern_helper(&generate_pattern(0, 10, 4).unwrap(), &reload);
|
||||
let result = new_prober.full_page_probe(pattern, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result);
|
||||
|
||||
let pattern = pattern_helper(generate_pattern(0, 6, 8).unwrap(), &reload);
|
||||
let pattern = pattern_helper(&generate_pattern(0, 6, 8).unwrap(), &reload);
|
||||
let result = new_prober.full_page_probe(pattern, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result);
|
||||
|
||||
let pattern = pattern_helper(generate_pattern(2, 6, 0).unwrap(), &reload);
|
||||
let pattern = pattern_helper(&generate_pattern(2, 6, 0).unwrap(), &reload);
|
||||
let result = new_prober.full_page_probe(pattern, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result);
|
||||
|
||||
let pattern = pattern_helper(vec![0, 0, 8, 8, 16, 16, 24, 24], &reload);
|
||||
let pattern = pattern_helper(&vec![0, 0, 8, 8, 16, 16, 24, 24], &reload);
|
||||
let result = new_prober.full_page_probe(pattern, NUM_ITERATION as u32, 100);
|
||||
println!("{}", result);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user