@@ -818,3 +818,115 @@ pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T
818
818
crate :: intrinsics:: select_unpredictable ( condition, true_val, false_val) . assume_init ( )
819
819
}
820
820
}
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