From ffb763bed483851ed4cd012760c665be0200c892 Mon Sep 17 00:00:00 2001 From: Guillaume DIDIER Date: Wed, 21 Sep 2022 11:00:01 +0200 Subject: [PATCH] Add the all_experiment binary and scripts (cherry picked from commit 05e56d9a71d0933ac226c075a54c1950996984b9) --- prefetcher_reverse/run-msr-all.sh | 7 + prefetcher_reverse/src/bin/all_experiments.rs | 283 ++++++++++++++++++ 2 files changed, 290 insertions(+) create mode 100755 prefetcher_reverse/run-msr-all.sh create mode 100644 prefetcher_reverse/src/bin/all_experiments.rs diff --git a/prefetcher_reverse/run-msr-all.sh b/prefetcher_reverse/run-msr-all.sh new file mode 100755 index 0000000..4c3f961 --- /dev/null +++ b/prefetcher_reverse/run-msr-all.sh @@ -0,0 +1,7 @@ +#!/bin/bash +PREFETCH_MSR=$1 +sudo wrmsr -a 0x1a4 $PREFETCH_MSR +sudo rdmsr -a 0x1a4 +cargo run --bin all_experiments --release > with-${PREFETCH_MSR}-prefetcher.log + + diff --git a/prefetcher_reverse/src/bin/all_experiments.rs b/prefetcher_reverse/src/bin/all_experiments.rs new file mode 100644 index 0000000..f426903 --- /dev/null +++ b/prefetcher_reverse/src/bin/all_experiments.rs @@ -0,0 +1,283 @@ +/* + 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, + tag: &str, + 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{}", tag), 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{}", tag), 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 + */ + +fn main() { + // TODO Argument parsing + let args = Params { + limit: 2, + same_ip: true, + unique_ip: true, + }; + + let mut experiments: Vec<(String, usize, usize, Box Vec>)> = vec![]; + for class in [ + ( + "", + Box::new(|k: usize| { + + let f = Box::new(move |i, j| { + let v = vec![ + i,j, + ]; + v.truncate(k); + v + }) as Box Vec>; + let i_limit = if k > 0 { + PAGE_CACHELINE_LEN + } else { + 1 + }; + let j_limit = if k > 1 { + PAGE_CACHELINE_LEN + } else { + 1 + }; + (i_limit,j_limit,f) + }) as Box (usize, usize, Box Vec>)>, + ), + ] { + for k in [0,1,2] { + let exp = class.1(k); + experiments.push((format!("{}{}", class.0, k),exp.1, exp.2, exp.3)); + } + } + + for class in [ + ( + "A", + Box::new(|k| { + Box::new(move |i, j| vec![i, (i + k) % PAGE_CACHELINE_LEN, j]) + as Box Vec> + }) as Box Box Vec>>, + ), + ( + "B", + Box::new(|k| { + Box::new(move |i, j| vec![i, (i - k) % PAGE_CACHELINE_LEN, j]) + as Box Vec> + }) as Box Box Vec>>, + ), + ( + "C", + Box::new(|k| { + Box::new(move |i, j| vec![i, j, (j + k) % PAGE_CACHELINE_LEN]) + as Box Vec> + }) as Box Box Vec>>, + ), + ( + "D", + Box::new(|k| { + Box::new(move |i, j| vec![i, j, (j - k) % PAGE_CACHELINE_LEN]) + as Box Vec> + }) as Box Box Vec>>, + ), + ] { + for k in [1, 2, 3, 4, 8] { + experiments.push((format!("{}{}", class.0, k), PAGE_CACHELINE_LEN, PAGE_CACHELINE_LEN, class.1(k))); + } + } + + for class in [( + "E", + Box::new(|len: usize| { + Box::new(move |base, stride| { + let mut res = vec![base]; + for i in 0..len { + res.push((base + stride * (i + 1)) % PAGE_CACHELINE_LEN) + } + res + }) as Box Vec> + }) as Box Box Vec>>, + )] { + for len in [2, 3, 4] { + experiments.push((format!("{}{}", class.0, len), PAGE_CACHELINE_LEN, PAGE_CACHELINE_LEN, class.1(len))); + } + } + + for class in [ + ( + "F", + Box::new(|k: isize| { + Box::new(move |i, j| { + vec![ + i, + (i as isize + k + PAGE_CACHELINE_LEN as isize) as usize + % PAGE_CACHELINE_LEN, + j, + (i as isize + 2 * k + PAGE_CACHELINE_LEN as isize) as usize + % PAGE_CACHELINE_LEN, + ] + }) as Box Vec> + }) as Box Box Vec>>, + ), + ] { + for k in [4 as isize, 3, 2, 1, -1, -2, -3, -4] { + experiments.push((format!("{}{}", class.0, k), PAGE_CACHELINE_LEN, PAGE_CACHELINE_LEN, class.1(k))); + } + } + + let mut prober = Prober::<1>::new(63).unwrap(); + + for experiment in experiments { + let tag = &experiment.0; + let mut patterns = vec![]; + for i in 0..experiment.1 { + for j in 0..experiment.2 { + patterns.push(experiment.3(i, j)) + } + } + let i = patterns[0].len(); + exp(i, tag, &patterns, args.same_ip, args.unique_ip, &mut prober); + } +}