2020-05-28 11:22:50 +02:00
|
|
|
use crate::complex_addressing::CacheSlicing::{
|
|
|
|
ComplexAddressing, NoSlice, SimpleAddressing, Unsupported,
|
|
|
|
};
|
2020-05-27 14:02:19 +02:00
|
|
|
use cpuid::MicroArchitecture;
|
|
|
|
|
2020-05-28 11:22:50 +02:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
2020-05-27 14:02:19 +02:00
|
|
|
pub enum CacheSlicing {
|
|
|
|
Unsupported,
|
|
|
|
ComplexAddressing(&'static [usize]),
|
2020-06-03 08:49:10 +02:00
|
|
|
SimpleAddressing(usize),
|
2020-05-27 14:02:19 +02:00
|
|
|
NoSlice,
|
|
|
|
}
|
2020-05-28 11:22:50 +02:00
|
|
|
const SANDYBRIDGE_TO_SKYLAKE_FUNCTIONS: [usize; 4] = [
|
2020-05-27 14:02:19 +02:00
|
|
|
0b0110_1101_0111_1101_0101_1101_0101_0001_000000,
|
|
|
|
0b1011_1010_1101_0111_1110_1010_1010_0010_000000,
|
|
|
|
0b1111_0011_0011_0011_0010_0100_1100_0100_000000,
|
2020-05-28 11:22:50 +02:00
|
|
|
0b0, // TODO
|
2020-05-27 14:02:19 +02:00
|
|
|
];
|
|
|
|
// missing functions for more than 8 cores.
|
|
|
|
|
|
|
|
pub fn cache_slicing(uarch: MicroArchitecture, physical_cores: u8) -> CacheSlicing {
|
|
|
|
let trailing_zeros = physical_cores.trailing_zeros();
|
|
|
|
if physical_cores != (1 << trailing_zeros) {
|
|
|
|
return Unsupported;
|
|
|
|
}
|
|
|
|
|
|
|
|
match uarch {
|
|
|
|
MicroArchitecture::Skylake
|
|
|
|
| MicroArchitecture::KabyLake
|
|
|
|
| MicroArchitecture::CoffeeLake => {
|
|
|
|
ComplexAddressing(&SANDYBRIDGE_TO_SKYLAKE_FUNCTIONS[0..((trailing_zeros + 1) as usize)])
|
2020-06-03 08:49:10 +02:00
|
|
|
},
|
2020-06-02 17:29:55 +02:00
|
|
|
MicroArchitecture::SandyBridge
|
|
|
|
| MicroArchitecture::Haswell | MicroArchitecture::HaswellE
|
|
|
|
| MicroArchitecture::Broadwell
|
|
|
|
| MicroArchitecture::IvyBridge | MicroArchitecture::IvyBridgeE => {
|
2020-05-28 11:22:50 +02:00
|
|
|
ComplexAddressing(&SANDYBRIDGE_TO_SKYLAKE_FUNCTIONS[0..((trailing_zeros) as usize)])
|
2020-06-03 08:49:10 +02:00
|
|
|
},
|
|
|
|
MicroArchitecture::Nehalem | MicroArchitecture::Westmere => {
|
2020-06-04 14:06:38 +02:00
|
|
|
SimpleAddressing(((physical_cores -1) as usize) << 6 + 8)// Hardcoded for 4 cores FIXME !!!
|
2020-05-28 11:22:50 +02:00
|
|
|
}
|
2020-05-27 14:02:19 +02:00
|
|
|
_ => Unsupported,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-28 11:22:50 +02:00
|
|
|
fn hash(addr: usize, mask: usize) -> usize {
|
|
|
|
((addr & mask).count_ones() & 1) as usize
|
2020-04-06 11:14:05 +02:00
|
|
|
}
|
|
|
|
|
2020-05-28 11:22:50 +02:00
|
|
|
impl CacheSlicing {
|
|
|
|
pub fn can_hash(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Unsupported | NoSlice => false,
|
|
|
|
ComplexAddressing(_) | SimpleAddressing(_) => true,
|
|
|
|
}
|
2020-04-06 11:14:05 +02:00
|
|
|
}
|
2020-05-28 11:22:50 +02:00
|
|
|
pub fn hash(&self, addr: usize) -> Option<usize> {
|
|
|
|
match self {
|
2020-07-02 15:39:37 +02:00
|
|
|
SimpleAddressing(mask) => Some(addr & *mask),
|
2020-05-28 11:22:50 +02:00
|
|
|
ComplexAddressing(masks) => {
|
|
|
|
let mut res = 0;
|
|
|
|
for mask in *masks {
|
|
|
|
res <<= 1;
|
|
|
|
res |= hash(addr, *mask);
|
|
|
|
}
|
|
|
|
Some(res)
|
|
|
|
}
|
|
|
|
_ => None,
|
2020-04-06 11:14:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|