Vc 1.4.5
SIMD Vector Classes for C++
 
Loading...
Searching...
No Matches
loadstoreflags.h
1/* This file is part of the Vc library. {{{
2Copyright © 2013-2015 Matthias Kretz <kretz@kde.org>
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the names of contributing organizations nor the
12 names of its contributors may be used to endorse or promote products
13 derived from this software without specific prior written permission.
14
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26}}}*/
27
28#ifndef VC_COMMON_LOADSTOREFLAGS_H_
29#define VC_COMMON_LOADSTOREFLAGS_H_
30
31#include "../traits/type_traits.h"
32
33namespace Vc_VERSIONED_NAMESPACE
34{
35
41struct Exclusive {};
45struct Shared {};
46
47namespace LoadStoreFlags
48{
49
50struct StreamingFlag {};
51struct UnalignedFlag {};
52struct PrefetchFlagBase {};
53// TODO: determine a good default for typical CPU use
54template <size_t L1 = 16 * 64, size_t L2 = 128 * 64, typename ExclusiveOrShared_ = void>
55struct PrefetchFlag : public PrefetchFlagBase {
56 typedef ExclusiveOrShared_ ExclusiveOrShared;
57 static constexpr size_t L1Stride = L1;
58 static constexpr size_t L2Stride = L2;
59 static constexpr bool IsExclusive = std::is_same<ExclusiveOrShared, Exclusive>::value;
60 static constexpr bool IsShared = std::is_same<ExclusiveOrShared, Shared>::value;
61};
62
63template<typename Base, typename Default, typename... LoadStoreFlags> struct ExtractType
64{
65 typedef Default type;
66};
67template<typename Base, typename Default, typename T, typename... LoadStoreFlags> struct ExtractType<Base, Default, T, LoadStoreFlags...>
68{
69 typedef typename std::conditional<std::is_base_of<Base, T>::value, T, typename ExtractType<Base, Default, LoadStoreFlags...>::type>::type type;
70};
71
72// ICC warns about the constexpr members in LoadStoreFlags: member "LoadStoreFlags<Flags...>::IsAligned" was declared but never referenced
73// who needs that warning, especially if it was referenced...
74// The warning cannot be reenabled because it gets emitted whenever the LoadStoreFlags is instantiated
75// somewhere, so it could be anywhere.
76#ifdef Vc_ICC
77#pragma warning(disable: 177)
78#endif
83template<typename... Flags> struct LoadStoreFlags
84{
85private:
86 // ICC doesn't grok this line:
87 //template<typename Test> using TestFlag = std::is_same<typename ExtractType<StreamingFlag, void, Flags...>::type, void>;
88 typedef typename ExtractType<PrefetchFlagBase, PrefetchFlag<0, 0>, Flags...>::type Prefetch;
89
90public:
91 constexpr LoadStoreFlags() {}
92
93 static constexpr bool IsStreaming = !std::is_same<typename ExtractType<StreamingFlag, void, Flags...>::type, void>::value;
94 static constexpr bool IsUnaligned = !std::is_same<typename ExtractType<UnalignedFlag, void, Flags...>::type, void>::value;
95 static constexpr bool IsAligned = !IsUnaligned;
96 static constexpr bool IsPrefetch = !std::is_same<typename ExtractType<PrefetchFlagBase, void, Flags...>::type, void>::value;
97 static constexpr bool IsExclusivePrefetch = Prefetch::IsExclusive;
98 static constexpr bool IsSharedPrefetch = Prefetch::IsShared;
99 static constexpr size_t L1Stride = Prefetch::L1Stride;
100 static constexpr size_t L2Stride = Prefetch::L2Stride;
101
102 typedef LoadStoreFlags<typename std::conditional<std::is_same<Flags, UnalignedFlag>::value, void, Flags>::type...> UnalignedRemoved;
103
104 // The following EnableIf* convenience types cannot use enable_if because then no LoadStoreFlags type
105 // could ever be instantiated. Instead these types are defined either as void* or void. The
106 // function that does SFINAE then assigns "= nullptr" to this type. Thus, the ones with just
107 // void result in substitution failure.
108 typedef typename std::conditional<IsAligned && !IsStreaming, void *, void>::type EnableIfAligned;
109 typedef typename std::conditional<IsAligned && IsStreaming, void *, void>::type EnableIfStreaming;
110 typedef typename std::conditional<IsUnaligned && !IsStreaming, void *, void>::type EnableIfUnalignedNotStreaming;
111 typedef typename std::conditional<IsUnaligned && IsStreaming, void *, void>::type EnableIfUnalignedAndStreaming;
112 typedef typename std::conditional<IsUnaligned , void *, void>::type EnableIfUnaligned;
113 typedef typename std::conditional<!IsUnaligned , void *, void>::type EnableIfNotUnaligned;
114 typedef typename std::conditional<IsPrefetch , void *, void>::type EnableIfPrefetch;
115 typedef typename std::conditional<!IsPrefetch , void *, void>::type EnableIfNotPrefetch;
116};
117
121template<> struct LoadStoreFlags<>
122{
123 constexpr LoadStoreFlags() {}
124
125 static constexpr bool IsStreaming = false;
126 static constexpr bool IsUnaligned = false;
127 static constexpr bool IsAligned = !IsUnaligned;
128 static constexpr bool IsPrefetch = false;
129 static constexpr bool IsExclusivePrefetch = false;
130 static constexpr bool IsSharedPrefetch = false;
131 static constexpr size_t L1Stride = 0;
132 static constexpr size_t L2Stride = 0;
133 typedef void* EnableIfAligned;
134 typedef void* EnableIfNotUnaligned;
135 typedef void* EnableIfNotPrefetch;
136};
137
146template<typename... LFlags, typename... RFlags>
147constexpr LoadStoreFlags<LFlags..., RFlags...> operator|(LoadStoreFlags<LFlags...>, LoadStoreFlags<RFlags...>)
148{
149 return LoadStoreFlags<LFlags..., RFlags...>();
150}
151
152} // LoadStoreFlags namespace
153
154using LoadStoreFlags::PrefetchFlag;
155
156typedef LoadStoreFlags::LoadStoreFlags<> AlignedTag;
157typedef LoadStoreFlags::LoadStoreFlags<LoadStoreFlags::StreamingFlag> StreamingTag;
158typedef LoadStoreFlags::LoadStoreFlags<LoadStoreFlags::UnalignedFlag> UnalignedTag;
159
161typedef UnalignedTag DefaultLoadTag;
163typedef UnalignedTag DefaultStoreTag;
164
178constexpr AlignedTag Aligned;
179
191constexpr UnalignedTag Unaligned;
192
206constexpr StreamingTag Streaming;
207
212constexpr LoadStoreFlags::LoadStoreFlags<PrefetchFlag<>> PrefetchDefault;
214
220template <size_t L1 = PrefetchFlag<>::L1Stride,
221 size_t L2 = PrefetchFlag<>::L2Stride,
222 typename ExclusiveOrShared = PrefetchFlag<>::ExclusiveOrShared>
223struct Prefetch : public LoadStoreFlags::LoadStoreFlags<PrefetchFlag<L1, L2, ExclusiveOrShared>>
224{
225};
226
227namespace Traits
228{
230template <typename... Ts>
231struct is_loadstoreflag_internal<LoadStoreFlags::LoadStoreFlags<Ts...>> : public std::true_type
232{
233};
236template <size_t L1, size_t L2, typename ExclusiveOrShared>
237struct is_loadstoreflag_internal<Prefetch<L1, L2, ExclusiveOrShared>> : public std::true_type
238{
239};
240} // namespace Traits
241} // namespace Vc
242
243#endif // VC_COMMON_LOADSTOREFLAGS_H_
constexpr LoadStoreFlags::LoadStoreFlags< PrefetchFlag<> > PrefetchDefault
Use this object for a flags parameter to request default software prefetches to be emitted.
constexpr UnalignedTag Unaligned
Use this object for a flags parameter to request unaligned loads and stores.
constexpr AlignedTag Aligned
Use this object for a flags parameter to request aligned loads and stores.
constexpr StreamingTag Streaming
Use this object for a flags parameter to request streaming loads and stores.
UnalignedTag DefaultLoadTag
The default load tag type uses unaligned (non-streaming) loads.
UnalignedTag DefaultStoreTag
The default store tag type uses unaligned (non-streaming) stores.
Hint for Prefetch to select prefetches that mark the memory as exclusive.
Hint for Prefetch to select prefetches that mark the memory as shared.