Skip to content

Commit 6407023

Browse files
committed
Add a separate function for a non-temporal read prefetch
1 parent a3b78e0 commit 6407023

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

library/core/src/hint.rs

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -831,18 +831,14 @@ where
831831
///
832832
/// The locality is just a hint, and may be ignored on some targets or by the hardware.
833833
///
834-
/// Used with functions like [`prefetch_read_data`] and [`prefetch_write_data`].
834+
/// Used with functions like [`prefetch_read`] and [`prefetch_write`].
835835
///
836-
/// [`prefetch_read_data`]: crate::hint::prefetch_read_data
837-
/// [`prefetch_write_data`]: crate::hint::prefetch_write_data
836+
/// [`prefetch_read`]: crate::hint::prefetch_read
837+
/// [`prefetch_write`]: crate::hint::prefetch_write
838838
#[unstable(feature = "hint_prefetch", issue = "146941")]
839839
#[non_exhaustive]
840840
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
841841
pub enum Locality {
842-
/// Data is unlikely to be reused soon.
843-
///
844-
/// Typically bypasses the caches so they are not polluted.
845-
NonTemporal = 0,
846842
/// Data is expected to be reused eventually.
847843
///
848844
/// Typically prefetches into L3 cache (if the CPU supports it).
@@ -870,30 +866,46 @@ pub enum Locality {
870866
/// # Examples
871867
///
872868
/// ```
873-
/// use std::hint::{Locality, prefetch_read_data};
869+
/// #![feature(hint_prefetch)]
870+
/// use std::hint::{Locality, prefetch_read};
874871
/// use std::mem::size_of_val;
875872
///
876873
/// // Prefetch all of `slice` into the L1 cache.
877874
/// fn prefetch_slice<T>(slice: &[T]) {
878875
/// // On most systems the cache line size is 64 bytes.
879876
/// for offset in (0..size_of_val(slice)).step_by(64) {
880-
/// prefetch_read_data(slice.as_ptr().wrapping_add(offset), Locality::L1);
877+
/// prefetch_read(slice.as_ptr().wrapping_add(offset), Locality::L1);
881878
/// }
882879
/// }
883880
/// ```
884881
#[inline(always)]
885882
#[unstable(feature = "hint_prefetch", issue = "146941")]
886-
pub const fn prefetch_read_data<T>(ptr: *const T, locality: Locality) {
883+
pub const fn prefetch_read<T>(ptr: *const T, locality: Locality) {
887884
match locality {
888-
Locality::NonTemporal => {
889-
intrinsics::prefetch_read_data::<T, { Locality::NonTemporal as i32 }>(ptr)
890-
}
891885
Locality::L3 => intrinsics::prefetch_read_data::<T, { Locality::L3 as i32 }>(ptr),
892886
Locality::L2 => intrinsics::prefetch_read_data::<T, { Locality::L2 as i32 }>(ptr),
893887
Locality::L1 => intrinsics::prefetch_read_data::<T, { Locality::L1 as i32 }>(ptr),
894888
}
895889
}
896890

891+
/// Prefetch the cache line containing `ptr` for a single future read, but attempt to avoid
892+
/// polluting the cache.
893+
///
894+
/// A strategically placed prefetch can reduce cache miss latency if the data is accessed
895+
/// soon after, but may also increase bandwidth usage or evict other cache lines.
896+
///
897+
/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.
898+
///
899+
/// Passing a dangling or invalid pointer is permitted: the memory will not
900+
/// actually be dereferenced, and no faults are raised.
901+
#[inline(always)]
902+
#[unstable(feature = "hint_prefetch", issue = "146941")]
903+
pub const fn prefetch_read_non_temporal<T>(ptr: *const T, locality: Locality) {
904+
// The LLVM intrinsic does not currently support specifying the locality.
905+
let _ = locality;
906+
intrinsics::prefetch_read_data::<T, 0>(ptr)
907+
}
908+
897909
/// Prefetch the cache line containing `ptr` for a future write.
898910
///
899911
/// A strategically placed prefetch can reduce cache miss latency if the data is accessed
@@ -903,19 +915,35 @@ pub const fn prefetch_read_data<T>(ptr: *const T, locality: Locality) {
903915
///
904916
/// Passing a dangling or invalid pointer is permitted: the memory will not
905917
/// actually be dereferenced, and no faults are raised.
918+
#[inline(always)]
906919
#[unstable(feature = "hint_prefetch", issue = "146941")]
907-
pub const fn prefetch_write_data<T>(ptr: *mut T, locality: Locality) {
920+
pub const fn prefetch_write<T>(ptr: *mut T, locality: Locality) {
908921
match locality {
909-
Locality::NonTemporal => {
910-
intrinsics::prefetch_write_data::<T, { Locality::NonTemporal as i32 }>(ptr)
911-
}
912922
Locality::L3 => intrinsics::prefetch_write_data::<T, { Locality::L3 as i32 }>(ptr),
913923
Locality::L2 => intrinsics::prefetch_write_data::<T, { Locality::L2 as i32 }>(ptr),
914924
Locality::L1 => intrinsics::prefetch_write_data::<T, { Locality::L1 as i32 }>(ptr),
915925
}
916926
}
917927

918-
/// Prefetch the cache line containing `ptr` for a future read.
928+
/// Prefetch the cache line containing `ptr` for a single future write, but attempt to avoid
929+
/// polluting the cache.
930+
///
931+
/// A strategically placed prefetch can reduce cache miss latency if the data is accessed
932+
/// soon after, but may also increase bandwidth usage or evict other cache lines.
933+
///
934+
/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.
935+
///
936+
/// Passing a dangling or invalid pointer is permitted: the memory will not
937+
/// actually be dereferenced, and no faults are raised.
938+
#[inline(always)]
939+
#[unstable(feature = "hint_prefetch", issue = "146941")]
940+
pub const fn prefetch_write_non_temporal<T>(ptr: *const T, locality: Locality) {
941+
// The LLVM intrinsic does not currently support specifying the locality.
942+
let _ = locality;
943+
intrinsics::prefetch_write_data::<T, 0>(ptr)
944+
}
945+
946+
/// Prefetch the cache line containing `ptr` into the instruction cache for a future read.
919947
///
920948
/// A strategically placed prefetch can reduce cache miss latency if the instructions are
921949
/// accessed soon after, but may also increase bandwidth usage or evict other cache lines.
@@ -924,12 +952,10 @@ pub const fn prefetch_write_data<T>(ptr: *mut T, locality: Locality) {
924952
///
925953
/// Passing a dangling or invalid pointer is permitted: the memory will not
926954
/// actually be dereferenced, and no faults are raised.
955+
#[inline(always)]
927956
#[unstable(feature = "hint_prefetch", issue = "146941")]
928957
pub const fn prefetch_read_instruction<T>(ptr: *const T, locality: Locality) {
929958
match locality {
930-
Locality::NonTemporal => {
931-
intrinsics::prefetch_read_instruction::<T, { Locality::NonTemporal as i32 }>(ptr)
932-
}
933959
Locality::L3 => intrinsics::prefetch_read_instruction::<T, { Locality::L3 as i32 }>(ptr),
934960
Locality::L2 => intrinsics::prefetch_read_instruction::<T, { Locality::L2 as i32 }>(ptr),
935961
Locality::L1 => intrinsics::prefetch_read_instruction::<T, { Locality::L1 as i32 }>(ptr),

0 commit comments

Comments
 (0)