File indexing completed on 2025-01-30 10:25:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef VC_COMMON_X86_PREFETCHES_H_
0029 #define VC_COMMON_X86_PREFETCHES_H_
0030
0031 #include <xmmintrin.h>
0032 #include "macros.h"
0033
0034 namespace Vc_VERSIONED_NAMESPACE
0035 {
0036 namespace Common
0037 {
0038
0039 static constexpr int exclusive_hint = 0;
0040
0041
0042
0043 template <typename ExclusiveOrShared = Vc::Shared>
0044 Vc_INTRINSIC void prefetchForOneRead(const void *addr)
0045 {
0046 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
0047 _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)), _MM_HINT_NTA);
0048 } else {
0049 _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)),
0050 static_cast<decltype(_MM_HINT_NTA)>(_MM_HINT_NTA | exclusive_hint));
0051 }
0052 }
0053 template <typename ExclusiveOrShared = Vc::Shared>
0054 Vc_INTRINSIC void prefetchClose(const void *addr)
0055 {
0056 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
0057 _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)), _MM_HINT_T0);
0058 } else {
0059 _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)),
0060 static_cast<decltype(_MM_HINT_T0)>(_MM_HINT_T0 | exclusive_hint));
0061 }
0062 }
0063 template <typename ExclusiveOrShared = Vc::Shared>
0064 Vc_INTRINSIC void prefetchMid(const void *addr)
0065 {
0066 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
0067 _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)), _MM_HINT_T1);
0068 } else {
0069 _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)),
0070 static_cast<decltype(_MM_HINT_T1)>(_MM_HINT_T1 | exclusive_hint));
0071 }
0072 }
0073 template <typename ExclusiveOrShared = Vc::Shared>
0074 Vc_INTRINSIC void prefetchFar(const void *addr)
0075 {
0076 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
0077 _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)), _MM_HINT_T2);
0078 } else {
0079 _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)),
0080 static_cast<decltype(_MM_HINT_T2)>(_MM_HINT_T2 | exclusive_hint));
0081 }
0082 }
0083
0084
0085 namespace
0086 {
0087 template<size_t L1, size_t L2, bool UseExclusivePrefetch> Vc_INTRINSIC void handlePrefetch(const void *addr_, typename std::enable_if<L1 != 0 && L2 != 0, void *>::type = nullptr)
0088 {
0089 const char *addr = static_cast<const char *>(addr_);
0090 prefetchClose<typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L1);
0091 prefetchMid <typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L2);
0092 }
0093 template<size_t L1, size_t L2, bool UseExclusivePrefetch> Vc_INTRINSIC void handlePrefetch(const void *addr_, typename std::enable_if<L1 == 0 && L2 != 0, void *>::type = nullptr)
0094 {
0095 const char *addr = static_cast<const char *>(addr_);
0096 prefetchMid <typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L2);
0097 }
0098 template<size_t L1, size_t L2, bool UseExclusivePrefetch> Vc_INTRINSIC void handlePrefetch(const void *addr_, typename std::enable_if<L1 != 0 && L2 == 0, void *>::type = nullptr)
0099 {
0100 const char *addr = static_cast<const char *>(addr_);
0101 prefetchClose<typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L1);
0102 }
0103 template<size_t L1, size_t L2, bool UseExclusivePrefetch> Vc_INTRINSIC void handlePrefetch(const void *, typename std::enable_if<L1 == 0 && L2 == 0, void *>::type = nullptr)
0104 {
0105 }
0106
0107 template<typename Flags> Vc_INTRINSIC void handleLoadPrefetches(const void * , Flags, typename Flags::EnableIfNotPrefetch = nullptr) {}
0108 template<typename Flags> Vc_INTRINSIC void handleLoadPrefetches(const void *addr, Flags, typename Flags::EnableIfPrefetch = nullptr)
0109 {
0110
0111 handlePrefetch<Flags::L1Stride, Flags::L2Stride, Flags::IsExclusivePrefetch>(addr);
0112 }
0113
0114 template<typename Flags> Vc_INTRINSIC void handleStorePrefetches(const void * , Flags, typename Flags::EnableIfNotPrefetch = nullptr) {}
0115 template<typename Flags> Vc_INTRINSIC void handleStorePrefetches(const void *addr, Flags, typename Flags::EnableIfPrefetch = nullptr)
0116 {
0117
0118 handlePrefetch<Flags::L1Stride, Flags::L2Stride, !Flags::IsSharedPrefetch>(addr);
0119 }
0120
0121 }
0122
0123
0124 }
0125
0126 using Common::prefetchForOneRead;
0127 using Common::prefetchClose;
0128 using Common::prefetchMid;
0129 using Common::prefetchFar;
0130 }
0131
0132 #endif
0133
0134