use crate::advanced::PrefetchStrategy;
#[inline]
pub unsafe fn apply_strategy(ptr: *mut u8, len: usize, strategy: PrefetchStrategy) {
match strategy {
PrefetchStrategy::None => {
},
PrefetchStrategy::Sequential => {
prefetch_sequential(ptr, len);
},
PrefetchStrategy::Random => {
},
PrefetchStrategy::Custom(lookahead) => {
prefetch_custom(ptr, len, lookahead);
},
}
}
#[inline]
unsafe fn prefetch_sequential(ptr: *mut u8, len: usize) {
let page_size = page_size();
let prefetch_pages = 4;
let prefetch_size = std::cmp::min(len, prefetch_pages * page_size);
for i in (0..prefetch_size).step_by(64) {
prefetch_read((ptr as usize + i) as *const u8);
}
}
#[inline]
unsafe fn prefetch_custom(ptr: *mut u8, len: usize, lookahead: usize) {
let prefetch_size = std::cmp::min(len, lookahead);
for i in (0..prefetch_size).step_by(64) {
prefetch_read((ptr as usize + i) as *const u8);
}
}
#[inline]
unsafe fn prefetch_read(ptr: *const u8) {
#[cfg(target_arch = "x86_64")]
{
std::arch::x86_64::_mm_prefetch(ptr as *const i8, std::arch::x86_64::_MM_HINT_T0);
}
#[cfg(target_arch = "aarch64")]
{
std::arch::aarch64::_prefetch(ptr, std::arch::aarch64::_PREFETCH_READ, std::arch::aarch64::_PREFETCH_LOCALITY3);
}
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
{
std::ptr::read_volatile(ptr);
}
}
#[inline]
fn page_size() -> usize {
#[cfg(unix)]
{
unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
}
#[cfg(windows)]
{
use winapi::um::sysinfoapi::{GetSystemInfo, SYSTEM_INFO};
unsafe {
let mut system_info: SYSTEM_INFO = std::mem::zeroed();
GetSystemInfo(&mut system_info);
system_info.dwPageSize as usize
}
}
#[cfg(not(any(unix, windows)))]
{
4096
}
}