Start working on cache calibration

This commit is contained in:
guillaume didier 2020-02-17 15:28:10 +01:00
parent aa72d2fa49
commit 00984ee2e0
3 changed files with 101 additions and 0 deletions

View File

@ -0,0 +1,70 @@
use crate::{flush, maccess, rdtsc_fence, rdtsc_nofence};
use polling_serial::{serial_print, serial_println};
use vga_buffer::println;
extern crate alloc;
use alloc::vec::Vec;
use core::cmp::min;
// calibration, todo
// this will require getting a nice page to do some amusing stuff on it.
// it will have to return some results later.
unsafe fn only_reload(p: *const u8) -> u64 {
let t = rdtsc_fence();
maccess(p);
let d = rdtsc_fence() - t;
d
}
unsafe fn flush_and_reload(p: *const u8) -> u64 {
flush(p);
let t = rdtsc_fence();
maccess(p);
let d = rdtsc_fence() - t;
d
}
pub fn calibrate_access() -> u64 {
serial_println!("Calibrating...");
let mut array = Vec::<usize>::with_capacity(5 << 10);
array.resize(5 << 10, 1);
let array = array.into_boxed_slice();
let mut hit_histogram = Vec::<u32>::with_capacity(80);
hit_histogram.resize(80, 0);
let mut miss_histogram = hit_histogram.clone();
let pointer = (&array[2048] as *const usize) as *const u8;
// sanity check
println!(
"&array[0]: {:p}, array[2048]{:p}",
(&array[0] as *const usize) as *const u8,
(&array[2048] as *const usize) as *const u8
);
unsafe { maccess(pointer) };
for _ in 0..(4 << 20) {
let d = unsafe { only_reload(pointer) };
hit_histogram[min(79, d / 5) as usize] += 1;
}
unsafe { flush(pointer) };
for _ in 0..(4 << 20) {
let d = unsafe { flush_and_reload(pointer) };
miss_histogram[min(79, d / 5) as usize] += 1;
}
// Todo plot and analyze histogram
serial_println!("Threshold {}", -1);
serial_println!("Calibration done.");
(-1_i64) as u64
}
pub fn calibrate_flush() -> u64 {
(-1_i64) as u64
}

View File

@ -1,4 +1,33 @@
#![no_std] #![no_std]
pub mod cache_info; pub mod cache_info;
pub mod calibration;
pub mod prefetcher; pub mod prefetcher;
use core::arch::x86_64 as arch_x86;
use core::ptr;
// rdtsc no fence
pub unsafe fn rdtsc_nofence() -> u64 {
arch_x86::_rdtsc()
}
// rdtsc (has mfence before and after)
pub unsafe fn rdtsc_fence() -> u64 {
arch_x86::_mm_mfence();
let tsc: u64 = arch_x86::_rdtsc();
arch_x86::_mm_mfence();
tsc
}
pub unsafe fn maccess<T>(p: *const T) -> () {
ptr::read_volatile(p);
}
// flush (cflush)
pub unsafe fn flush(p: *const u8) -> () {
arch_x86::_mm_clflush(p);
}
// future enhancements
// prefetch
// long nop (64 nops)

View File

@ -92,6 +92,8 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
cache_utils::prefetcher::prefetcher_status() cache_utils::prefetcher::prefetcher_status()
); );
cache_utils::calibration::calibrate_access();
// Calibration // Calibration
// disable pretechers // disable pretechers
// Calibrate hit / miss rdtsc threshold // Calibrate hit / miss rdtsc threshold