Warning, file /include/Vc/common/x86_prefetches.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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