28#ifndef VC_COMMON_X86_PREFETCHES_H_
29#define VC_COMMON_X86_PREFETCHES_H_
34namespace Vc_VERSIONED_NAMESPACE
39static constexpr int exclusive_hint = 0;
43template <
typename ExclusiveOrShared = Vc::Shared>
44Vc_INTRINSIC
void prefetchForOneRead(
const void *addr)
46 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
47 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)), _MM_HINT_NTA);
49 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)),
50 static_cast<decltype(_MM_HINT_NTA)
>(_MM_HINT_NTA | exclusive_hint));
53template <
typename ExclusiveOrShared = Vc::Shared>
54Vc_INTRINSIC
void prefetchClose(
const void *addr)
56 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
57 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)), _MM_HINT_T0);
59 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)),
60 static_cast<decltype(_MM_HINT_T0)
>(_MM_HINT_T0 | exclusive_hint));
63template <
typename ExclusiveOrShared = Vc::Shared>
64Vc_INTRINSIC
void prefetchMid(
const void *addr)
66 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
67 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)), _MM_HINT_T1);
69 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)),
70 static_cast<decltype(_MM_HINT_T1)
>(_MM_HINT_T1 | exclusive_hint));
73template <
typename ExclusiveOrShared = Vc::Shared>
74Vc_INTRINSIC
void prefetchFar(
const void *addr)
76 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
77 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)), _MM_HINT_T2);
79 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)),
80 static_cast<decltype(_MM_HINT_T2)
>(_MM_HINT_T2 | exclusive_hint));
87template<
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)
89 const char *addr =
static_cast<const char *
>(addr_);
90 prefetchClose<typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L1);
91 prefetchMid <typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L2);
93template<
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)
95 const char *addr =
static_cast<const char *
>(addr_);
96 prefetchMid <typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L2);
98template<
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)
100 const char *addr =
static_cast<const char *
>(addr_);
101 prefetchClose<typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L1);
103template<
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)
107template<
typename Flags> Vc_INTRINSIC
void handleLoadPrefetches(
const void * , Flags,
typename Flags::EnableIfNotPrefetch =
nullptr) {}
108template<
typename Flags> Vc_INTRINSIC
void handleLoadPrefetches(
const void *addr, Flags,
typename Flags::EnableIfPrefetch =
nullptr)
111 handlePrefetch<Flags::L1Stride, Flags::L2Stride, Flags::IsExclusivePrefetch>(addr);
114template<
typename Flags> Vc_INTRINSIC
void handleStorePrefetches(
const void * , Flags,
typename Flags::EnableIfNotPrefetch =
nullptr) {}
115template<
typename Flags> Vc_INTRINSIC
void handleStorePrefetches(
const void *addr, Flags,
typename Flags::EnableIfPrefetch =
nullptr)
118 handlePrefetch<Flags::L1Stride, Flags::L2Stride, !Flags::IsSharedPrefetch>(addr);
126using Common::prefetchForOneRead;
127using Common::prefetchClose;
128using Common::prefetchMid;
129using Common::prefetchFar;