@@ -823,3 +823,115 @@ where
823823 crate :: intrinsics:: select_unpredictable ( condition, true_val, false_val) . assume_init ( )
824824 }
825825}
826+
827+ /// The expected temporal locality of a memory prefetch operation.
828+ ///
829+ /// Locality expresses how likely the prefetched data is to be reused soon,
830+ /// and therefore which level of cache it should be brought into.
831+ ///
832+ /// The locality is just a hint, and may be ignored on some targets or by the hardware.
833+ ///
834+ /// Used with functions like [`prefetch_read_data`] and [`prefetch_write_data`].
835+ ///
836+ /// [`prefetch_read_data`]: crate::hint::prefetch_read_data
837+ /// [`prefetch_write_data`]: crate::hint::prefetch_write_data
838+ #[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
839+ #[ non_exhaustive]
840+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
841+ 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 ,
846+ /// Data is expected to be reused eventually.
847+ ///
848+ /// Typically prefetches into L3 cache (if the CPU supports it).
849+ L3 = 1 ,
850+ /// Data is expected to be reused in the near future.
851+ ///
852+ /// Typically prefetches into L2 cache.
853+ L2 = 2 ,
854+ /// Data is expected to be reused very soon.
855+ ///
856+ /// Typically prefetches into L1 cache.
857+ L1 = 3 ,
858+ }
859+
860+ /// Prefetch the cache line containing `ptr` for a future read.
861+ ///
862+ /// A strategically placed prefetch can reduce cache miss latency if the data is accessed
863+ /// soon after, but may also increase bandwidth usage or evict other cache lines.
864+ ///
865+ /// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.
866+ ///
867+ /// Passing a dangling or invalid pointer is permitted: the memory will not
868+ /// actually be dereferenced, and no faults are raised.
869+ ///
870+ /// # Examples
871+ ///
872+ /// ```
873+ /// use std::hint::{Locality, prefetch_read_data};
874+ /// use std::mem::size_of_val;
875+ ///
876+ /// // Prefetch all of `slice` into the L1 cache.
877+ /// fn prefetch_slice<T>(slice: &[T]) {
878+ /// // On most systems the cache line size is 64 bytes.
879+ /// for offset in (0..size_of_val(slice)).step_by(64) {
880+ /// prefetch_read_data(slice.as_ptr().wrapping_add(offset), Locality::L1);
881+ /// }
882+ /// }
883+ /// ```
884+ #[ inline( always) ]
885+ #[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
886+ pub const fn prefetch_read_data < T > ( ptr : * const T , locality : Locality ) {
887+ match locality {
888+ Locality :: NonTemporal => {
889+ intrinsics:: prefetch_read_data :: < T , { Locality :: NonTemporal as i32 } > ( ptr)
890+ }
891+ Locality :: L3 => intrinsics:: prefetch_read_data :: < T , { Locality :: L3 as i32 } > ( ptr) ,
892+ Locality :: L2 => intrinsics:: prefetch_read_data :: < T , { Locality :: L2 as i32 } > ( ptr) ,
893+ Locality :: L1 => intrinsics:: prefetch_read_data :: < T , { Locality :: L1 as i32 } > ( ptr) ,
894+ }
895+ }
896+
897+ /// Prefetch the cache line containing `ptr` for a future write.
898+ ///
899+ /// A strategically placed prefetch can reduce cache miss latency if the data is accessed
900+ /// soon after, but may also increase bandwidth usage or evict other cache lines.
901+ ///
902+ /// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.
903+ ///
904+ /// Passing a dangling or invalid pointer is permitted: the memory will not
905+ /// actually be dereferenced, and no faults are raised.
906+ #[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
907+ pub const fn prefetch_write_data < T > ( ptr : * mut T , locality : Locality ) {
908+ match locality {
909+ Locality :: NonTemporal => {
910+ intrinsics:: prefetch_write_data :: < T , { Locality :: NonTemporal as i32 } > ( ptr)
911+ }
912+ Locality :: L3 => intrinsics:: prefetch_write_data :: < T , { Locality :: L3 as i32 } > ( ptr) ,
913+ Locality :: L2 => intrinsics:: prefetch_write_data :: < T , { Locality :: L2 as i32 } > ( ptr) ,
914+ Locality :: L1 => intrinsics:: prefetch_write_data :: < T , { Locality :: L1 as i32 } > ( ptr) ,
915+ }
916+ }
917+
918+ /// Prefetch the cache line containing `ptr` for a future read.
919+ ///
920+ /// A strategically placed prefetch can reduce cache miss latency if the instructions are
921+ /// accessed soon after, but may also increase bandwidth usage or evict other cache lines.
922+ ///
923+ /// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.
924+ ///
925+ /// Passing a dangling or invalid pointer is permitted: the memory will not
926+ /// actually be dereferenced, and no faults are raised.
927+ #[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
928+ pub const fn prefetch_read_instruction < T > ( ptr : * const T , locality : Locality ) {
929+ match locality {
930+ Locality :: NonTemporal => {
931+ intrinsics:: prefetch_read_instruction :: < T , { Locality :: NonTemporal as i32 } > ( ptr)
932+ }
933+ Locality :: L3 => intrinsics:: prefetch_read_instruction :: < T , { Locality :: L3 as i32 } > ( ptr) ,
934+ Locality :: L2 => intrinsics:: prefetch_read_instruction :: < T , { Locality :: L2 as i32 } > ( ptr) ,
935+ Locality :: L1 => intrinsics:: prefetch_read_instruction :: < T , { Locality :: L1 as i32 } > ( ptr) ,
936+ }
937+ }
0 commit comments