@@ -826,18 +826,14 @@ pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T
826
826
///
827
827
/// The locality is just a hint, and may be ignored on some targets or by the hardware.
828
828
///
829
- /// Used with functions like [`prefetch_read_data `] and [`prefetch_write_data `].
829
+ /// Used with functions like [`prefetch_read `] and [`prefetch_write `].
830
830
///
831
- /// [`prefetch_read_data `]: crate::hint::prefetch_read_data
832
- /// [`prefetch_write_data `]: crate::hint::prefetch_write_data
831
+ /// [`prefetch_read `]: crate::hint::prefetch_read
832
+ /// [`prefetch_write `]: crate::hint::prefetch_write
833
833
#[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
834
834
#[ non_exhaustive]
835
835
#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
836
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
837
/// Data is expected to be reused eventually.
842
838
///
843
839
/// Typically prefetches into L3 cache (if the CPU supports it).
@@ -865,30 +861,46 @@ pub enum Locality {
865
861
/// # Examples
866
862
///
867
863
/// ```
868
- /// use std::hint::{Locality, prefetch_read_data};
864
+ /// #![feature(hint_prefetch)]
865
+ /// use std::hint::{Locality, prefetch_read};
869
866
/// use std::mem::size_of_val;
870
867
///
871
868
/// // Prefetch all of `slice` into the L1 cache.
872
869
/// fn prefetch_slice<T>(slice: &[T]) {
873
870
/// // On most systems the cache line size is 64 bytes.
874
871
/// for offset in (0..size_of_val(slice)).step_by(64) {
875
- /// prefetch_read_data (slice.as_ptr().wrapping_add(offset), Locality::L1);
872
+ /// prefetch_read (slice.as_ptr().wrapping_add(offset), Locality::L1);
876
873
/// }
877
874
/// }
878
875
/// ```
879
876
#[ inline( always) ]
880
877
#[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
881
- pub const fn prefetch_read_data < T > ( ptr : * const T , locality : Locality ) {
878
+ pub const fn prefetch_read < T > ( ptr : * const T , locality : Locality ) {
882
879
match locality {
883
- Locality :: NonTemporal => {
884
- intrinsics:: prefetch_read_data :: < T , { Locality :: NonTemporal as i32 } > ( ptr)
885
- }
886
880
Locality :: L3 => intrinsics:: prefetch_read_data :: < T , { Locality :: L3 as i32 } > ( ptr) ,
887
881
Locality :: L2 => intrinsics:: prefetch_read_data :: < T , { Locality :: L2 as i32 } > ( ptr) ,
888
882
Locality :: L1 => intrinsics:: prefetch_read_data :: < T , { Locality :: L1 as i32 } > ( ptr) ,
889
883
}
890
884
}
891
885
886
+ /// Prefetch the cache line containing `ptr` for a single future read, but attempt to avoid
887
+ /// polluting the cache.
888
+ ///
889
+ /// A strategically placed prefetch can reduce cache miss latency if the data is accessed
890
+ /// soon after, but may also increase bandwidth usage or evict other cache lines.
891
+ ///
892
+ /// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.
893
+ ///
894
+ /// Passing a dangling or invalid pointer is permitted: the memory will not
895
+ /// actually be dereferenced, and no faults are raised.
896
+ #[ inline( always) ]
897
+ #[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
898
+ pub const fn prefetch_read_non_temporal < T > ( ptr : * const T , locality : Locality ) {
899
+ // The LLVM intrinsic does not currently support specifying the locality.
900
+ let _ = locality;
901
+ intrinsics:: prefetch_read_data :: < T , 0 > ( ptr)
902
+ }
903
+
892
904
/// Prefetch the cache line containing `ptr` for a future write.
893
905
///
894
906
/// A strategically placed prefetch can reduce cache miss latency if the data is accessed
@@ -898,19 +910,35 @@ pub const fn prefetch_read_data<T>(ptr: *const T, locality: Locality) {
898
910
///
899
911
/// Passing a dangling or invalid pointer is permitted: the memory will not
900
912
/// actually be dereferenced, and no faults are raised.
913
+ #[ inline( always) ]
901
914
#[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
902
- pub const fn prefetch_write_data < T > ( ptr : * mut T , locality : Locality ) {
915
+ pub const fn prefetch_write < T > ( ptr : * mut T , locality : Locality ) {
903
916
match locality {
904
- Locality :: NonTemporal => {
905
- intrinsics:: prefetch_write_data :: < T , { Locality :: NonTemporal as i32 } > ( ptr)
906
- }
907
917
Locality :: L3 => intrinsics:: prefetch_write_data :: < T , { Locality :: L3 as i32 } > ( ptr) ,
908
918
Locality :: L2 => intrinsics:: prefetch_write_data :: < T , { Locality :: L2 as i32 } > ( ptr) ,
909
919
Locality :: L1 => intrinsics:: prefetch_write_data :: < T , { Locality :: L1 as i32 } > ( ptr) ,
910
920
}
911
921
}
912
922
913
- /// Prefetch the cache line containing `ptr` for a future read.
923
+ /// Prefetch the cache line containing `ptr` for a single future write, but attempt to avoid
924
+ /// polluting the cache.
925
+ ///
926
+ /// A strategically placed prefetch can reduce cache miss latency if the data is accessed
927
+ /// soon after, but may also increase bandwidth usage or evict other cache lines.
928
+ ///
929
+ /// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.
930
+ ///
931
+ /// Passing a dangling or invalid pointer is permitted: the memory will not
932
+ /// actually be dereferenced, and no faults are raised.
933
+ #[ inline( always) ]
934
+ #[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
935
+ pub const fn prefetch_write_non_temporal < T > ( ptr : * const T , locality : Locality ) {
936
+ // The LLVM intrinsic does not currently support specifying the locality.
937
+ let _ = locality;
938
+ intrinsics:: prefetch_write_data :: < T , 0 > ( ptr)
939
+ }
940
+
941
+ /// Prefetch the cache line containing `ptr` into the instruction cache for a future read.
914
942
///
915
943
/// A strategically placed prefetch can reduce cache miss latency if the instructions are
916
944
/// accessed soon after, but may also increase bandwidth usage or evict other cache lines.
@@ -919,12 +947,10 @@ pub const fn prefetch_write_data<T>(ptr: *mut T, locality: Locality) {
919
947
///
920
948
/// Passing a dangling or invalid pointer is permitted: the memory will not
921
949
/// actually be dereferenced, and no faults are raised.
950
+ #[ inline( always) ]
922
951
#[ unstable( feature = "hint_prefetch" , issue = "146941" ) ]
923
952
pub const fn prefetch_read_instruction < T > ( ptr : * const T , locality : Locality ) {
924
953
match locality {
925
- Locality :: NonTemporal => {
926
- intrinsics:: prefetch_read_instruction :: < T , { Locality :: NonTemporal as i32 } > ( ptr)
927
- }
928
954
Locality :: L3 => intrinsics:: prefetch_read_instruction :: < T , { Locality :: L3 as i32 } > ( ptr) ,
929
955
Locality :: L2 => intrinsics:: prefetch_read_instruction :: < T , { Locality :: L2 as i32 } > ( ptr) ,
930
956
Locality :: L1 => intrinsics:: prefetch_read_instruction :: < T , { Locality :: L1 as i32 } > ( ptr) ,
0 commit comments