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