From 559a4ecdf82db1b647964f1317ab01c2b7bdfdbf Mon Sep 17 00:00:00 2001 From: Guillume DIDIER Date: Tue, 25 Jan 2022 14:18:03 +0100 Subject: [PATCH] General updates --- Cargo.lock | 3 + prefetcher_reverse/Cargo.toml | 1 + prefetcher_reverse/MSR1A4.txt | 9 + prefetcher_reverse/run-msr-eap.sh | 8 + .../src/bin/exhaustive_access_pattern.rs | 165 ++++++++++++++++ .../src/bin/extra_access_pattern.rs | 183 ++++++++++++++++++ prefetcher_reverse/src/bin/ip_test.rs | 2 +- prefetcher_reverse/src/bin/new_page.rs | 4 +- prefetcher_reverse/src/bin/rpa_patterns.rs | 4 +- prefetcher_reverse/src/bin/stream.rs | 10 +- prefetcher_reverse/src/bin/strides.rs | 4 +- prefetcher_reverse/src/lib.rs | 67 ++++--- prefetcher_reverse/src/main.rs | 18 +- 13 files changed, 429 insertions(+), 49 deletions(-) create mode 100644 prefetcher_reverse/MSR1A4.txt create mode 100755 prefetcher_reverse/run-msr-eap.sh create mode 100644 prefetcher_reverse/src/bin/exhaustive_access_pattern.rs create mode 100644 prefetcher_reverse/src/bin/extra_access_pattern.rs diff --git a/Cargo.lock b/Cargo.lock index 2f6206b..c4be41b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/prefetcher_reverse/Cargo.toml b/prefetcher_reverse/Cargo.toml index e150af7..56636fe 100644 --- a/prefetcher_reverse/Cargo.toml +++ b/prefetcher_reverse/Cargo.toml @@ -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" diff --git a/prefetcher_reverse/MSR1A4.txt b/prefetcher_reverse/MSR1A4.txt new file mode 100644 index 0000000..5ba7bfc --- /dev/null +++ b/prefetcher_reverse/MSR1A4.txt @@ -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 diff --git a/prefetcher_reverse/run-msr-eap.sh b/prefetcher_reverse/run-msr-eap.sh new file mode 100755 index 0000000..3d9ad0d --- /dev/null +++ b/prefetcher_reverse/run-msr-eap.sh @@ -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 + diff --git a/prefetcher_reverse/src/bin/exhaustive_access_pattern.rs b/prefetcher_reverse/src/bin/exhaustive_access_pattern.rs new file mode 100644 index 0000000..b4d4535 --- /dev/null +++ b/prefetcher_reverse/src/bin/exhaustive_access_pattern.rs @@ -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, 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>, + 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::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); + } +} diff --git a/prefetcher_reverse/src/bin/extra_access_pattern.rs b/prefetcher_reverse/src/bin/extra_access_pattern.rs new file mode 100644 index 0000000..2ba58e1 --- /dev/null +++ b/prefetcher_reverse/src/bin/extra_access_pattern.rs @@ -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, 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>, + 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::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); + } +} diff --git a/prefetcher_reverse/src/bin/ip_test.rs b/prefetcher_reverse/src/bin/ip_test.rs index ad0444b..11e7e05 100644 --- a/prefetcher_reverse/src/bin/ip_test.rs +++ b/prefetcher_reverse/src/bin/ip_test.rs @@ -1,4 +1,4 @@ -use prefetcher_reverse::ip_tool::tmp_test; +use cache_utils::ip_tool::tmp_test; fn main() { tmp_test(); diff --git a/prefetcher_reverse/src/bin/new_page.rs b/prefetcher_reverse/src/bin/new_page.rs index 823e6e0..5c4f6f9 100644 --- a/prefetcher_reverse/src/bin/new_page.rs +++ b/prefetcher_reverse/src/bin/new_page.rs @@ -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::>(); - 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); diff --git a/prefetcher_reverse/src/bin/rpa_patterns.rs b/prefetcher_reverse/src/bin/rpa_patterns.rs index d5fdeed..6c0c1ca 100644 --- a/prefetcher_reverse/src/bin/rpa_patterns.rs +++ b/prefetcher_reverse/src/bin/rpa_patterns.rs @@ -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); diff --git a/prefetcher_reverse/src/bin/stream.rs b/prefetcher_reverse/src/bin/stream.rs index d6d92b0..a992052 100644 --- a/prefetcher_reverse/src/bin/stream.rs +++ b/prefetcher_reverse/src/bin/stream.rs @@ -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::>(); - 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"); diff --git a/prefetcher_reverse/src/bin/strides.rs b/prefetcher_reverse/src/bin/strides.rs index 5dab7aa..526e37e 100644 --- a/prefetcher_reverse/src/bin/strides.rs +++ b/prefetcher_reverse/src/bin/strides.rs @@ -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::>(); - 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); diff --git a/prefetcher_reverse/src/lib.rs b/prefetcher_reverse/src/lib.rs index 215f85a..5da06bd 100644 --- a/prefetcher_reverse/src/lib.rs +++ b/prefetcher_reverse/src/lib.rs @@ -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 { pages: Vec>, ff_handles: Vec>, - //fr_handles: Vec>, - fr_handles: Vec>, + fr_handles: Vec>, + //fr_handles: Vec>, page_indexes: Peekable>>, 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, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct SingleProbeResult { pub probe_offset: usize, pub pattern_result: Vec, @@ -177,16 +176,16 @@ impl Prober { 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::::try_new(PAGE_LEN * GS, false, false, |j| { @@ -246,7 +245,9 @@ impl Prober { 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 Prober { 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 Prober { 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 Prober { ProbeResult::Flush(r) => r, ProbeResult::FullFlush(r) => r[offset], }, - }); + }; } result } @@ -537,12 +548,12 @@ pub fn reference_patterns() -> [(&'static str, Vec); 9] { ] } -pub fn pattern_helper<'a>(offsets: Vec, function: &'a Function) -> Vec> { +pub fn pattern_helper<'a>(offsets: &Vec, function: &'a Function) -> Vec> { offsets .into_iter() .map(|i| PatternAccess { function, - offset: i, + offset: *i, }) .collect() } diff --git a/prefetcher_reverse/src/main.rs b/prefetcher_reverse/src/main.rs index 174e11d..b070747 100644 --- a/prefetcher_reverse/src/main.rs +++ b/prefetcher_reverse/src/main.rs @@ -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);