NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
simd/memory.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_SIMD_MEMORY_HPP__
2#define NEFORCE_CORE_SIMD_MEMORY_HPP__
3
10
12NEFORCE_BEGIN_NAMESPACE__
13NEFORCE_BEGIN_SIMD__
14
19
26NEFORCE_ALWAYS_INLINE_INLINE vec128_t load_aligned(const void* ptr) noexcept {
27#ifdef NEFORCE_SIMD_SSE2
28 return ::_mm_load_si128(static_cast<const vec128_t*>(ptr));
29#elif defined(NEFORCE_SIMD_NEON)
30 return vld1q_u8(static_cast<const uint8_t*>(ptr));
31#else
32 vec128_t result;
33 const auto* src = static_cast<const byte_t*>(ptr);
34 for (int i = 0; i < 16; ++i) {
35 result.data[i] = src[i];
36 }
37 return result;
38#endif
39}
40
46NEFORCE_ALWAYS_INLINE_INLINE vec128_t loadu_si128(const void* ptr) noexcept {
47#ifdef NEFORCE_SIMD_SSE2
48 return ::_mm_loadu_si128(static_cast<const vec128_t*>(ptr));
49#elif defined(NEFORCE_SIMD_NEON)
50 return vld1q_u8(static_cast<const uint8_t*>(ptr));
51#else
52 vec128_t result;
53 const auto* src = static_cast<const byte_t*>(ptr);
54 for (int i = 0; i < 16; ++i) {
55 result.data[i] = src[i];
56 }
57 return result;
58#endif
59}
60
66NEFORCE_ALWAYS_INLINE_INLINE vec256_t loadu_si256(const void* ptr) noexcept {
67#if defined(NEFORCE_SIMD_AVX)
68 return ::_mm256_loadu_si256(static_cast<const vec256_t*>(ptr));
69#else
70 vec256_t result;
71 const auto* src = static_cast<const byte_t*>(ptr);
72 for (int i = 0; i < 32; ++i) {
73 result.data[i] = src[i];
74 }
75 return result;
76#endif
77}
78
84NEFORCE_ALWAYS_INLINE_INLINE vec512_t loadu_si512(const void* ptr) noexcept {
85#ifdef NEFORCE_SIMD_AVX512F
86 return ::_mm512_loadu_si512(ptr);
87#else
88 vec512_t result;
89 const auto* src = static_cast<const byte_t*>(ptr);
90 for (int i = 0; i < 64; ++i) {
91 result.data[i] = src[i];
92 }
93 return result;
94#endif
95}
96
102NEFORCE_ALWAYS_INLINE_INLINE vec128f_t loadu_ps(const void* ptr) noexcept {
103#ifdef NEFORCE_SIMD_SSE2
104 return ::_mm_loadu_ps(static_cast<const float*>(ptr));
105#elif defined(NEFORCE_SIMD_NEON)
106 return vld1q_f32(static_cast<const float*>(ptr));
107#else
108 vec128f_t result;
109 const auto* src = static_cast<const float*>(ptr);
110 for (int i = 0; i < 4; ++i) {
111 result.data[i] = src[i];
112 }
113 return result;
114#endif
115}
116
122NEFORCE_ALWAYS_INLINE_INLINE vec128d_t loadu_pd(const void* ptr) noexcept {
123#ifdef NEFORCE_SIMD_SSE2
124 return ::_mm_loadu_pd(static_cast<const double*>(ptr));
125#elif defined(NEFORCE_SIMD_NEON)
126 return vld1q_f64(static_cast<const double*>(ptr));
127#else
128 vec128d_t result;
129 const auto* src = static_cast<const double*>(ptr);
130 for (int i = 0; i < 2; ++i) {
131 result.data[i] = src[i];
132 }
133 return result;
134#endif
135}
136
143NEFORCE_ALWAYS_INLINE_INLINE void store_aligned(void* ptr, vec128_t v) noexcept {
144#ifdef NEFORCE_SIMD_SSE2
145 ::_mm_store_si128(static_cast<vec128_t*>(ptr), v);
146#elif defined(NEFORCE_SIMD_NEON)
147 vst1q_u8(static_cast<uint8_t*>(ptr), v);
148#else
149 auto* dst = static_cast<byte_t*>(ptr);
150 for (int i = 0; i < 16; ++i) {
151 dst[i] = v.data[i];
152 }
153#endif
154}
155
161NEFORCE_ALWAYS_INLINE_INLINE void storeu_si128(void* ptr, vec128_t v) noexcept {
162#ifdef NEFORCE_SIMD_SSE2
163 ::_mm_storeu_si128(static_cast<vec128_t*>(ptr), v);
164#elif defined(NEFORCE_SIMD_NEON)
165 vst1q_u8(static_cast<uint8_t*>(ptr), v);
166#else
167 auto* dst = static_cast<byte_t*>(ptr);
168 for (int i = 0; i < 16; ++i) {
169 dst[i] = v.data[i];
170 }
171#endif
172}
173
179NEFORCE_ALWAYS_INLINE_INLINE void storeu_si256(void* ptr, vec256_t v) noexcept {
180#if defined(NEFORCE_SIMD_AVX)
181 ::_mm256_storeu_si256(static_cast<vec256_t*>(ptr), v);
182#else
183 auto* dst = static_cast<byte_t*>(ptr);
184 for (int i = 0; i < 32; ++i) {
185 dst[i] = v.data[i];
186 }
187#endif
188}
189
195NEFORCE_ALWAYS_INLINE_INLINE void storeu_si512(void* ptr, vec512_t v) noexcept {
196#ifdef NEFORCE_SIMD_AVX512F
197 ::_mm512_storeu_si512(ptr, v);
198#else
199 auto* dst = static_cast<byte_t*>(ptr);
200 for (int i = 0; i < 64; ++i) {
201 dst[i] = v.data[i];
202 }
203#endif
204}
205
213NEFORCE_ALWAYS_INLINE_INLINE void store_stream(void* ptr, vec128_t v) noexcept {
214#ifdef NEFORCE_SIMD_SSE2
215 ::_mm_stream_si128(static_cast<vec128_t*>(ptr), v);
216#elif defined(NEFORCE_SIMD_NEON)
217 vst1q_u8(static_cast<uint8_t*>(ptr), v);
218#else
219 auto* dst = static_cast<byte_t*>(ptr);
220 for (int i = 0; i < 16; ++i) {
221 dst[i] = v.data[i];
222 }
223#endif
224}
225
232NEFORCE_ALWAYS_INLINE_INLINE void store_stream256(void* ptr, vec256_t v) noexcept {
233#if defined(NEFORCE_SIMD_AVX)
234 ::_mm256_stream_si256(static_cast<vec256_t*>(ptr), v);
235#else
236 auto* dst = static_cast<byte_t*>(ptr);
237 for (int i = 0; i < 32; ++i) {
238 dst[i] = v.data[i];
239 }
240#endif
241}
242
249NEFORCE_ALWAYS_INLINE_INLINE void store_stream512(void* ptr, vec512_t v) noexcept {
250#ifdef NEFORCE_SIMD_AVX512F
251 ::_mm512_stream_si512(ptr, v);
252#else
253 auto* dst = static_cast<byte_t*>(ptr);
254 for (int i = 0; i < 64; ++i) {
255 dst[i] = v.data[i];
256 }
257#endif
258}
259
266NEFORCE_ALWAYS_INLINE_INLINE vec128_t load_stream(const void* ptr) noexcept {
267#if defined(NEFORCE_SIMD_SSE4_1)
268 return ::_mm_stream_load_si128(const_cast<vec128_t*>(static_cast<const vec128_t*>(ptr)));
269#else
270 return loadu_si128(ptr);
271#endif
272}
273
278NEFORCE_ALWAYS_INLINE_INLINE void prefetch_read(const void* ptr) noexcept {
279#ifdef NEFORCE_SIMD_SSE2
280 _mm_prefetch(static_cast<const char*>(ptr), _MM_HINT_T0);
281#elif defined(NEFORCE_SIMD_NEON)
282 __builtin_prefetch(ptr, 0, 3);
283#endif
284}
285
290NEFORCE_ALWAYS_INLINE_INLINE void prefetch_write(const void* ptr) noexcept {
291#ifdef NEFORCE_SIMD_SSE2
292 _mm_prefetch(static_cast<const char*>(ptr), _MM_HINT_T0);
293#elif defined(NEFORCE_SIMD_NEON)
294 __builtin_prefetch(ptr, 1, 3);
295#endif
296}
297
302NEFORCE_ALWAYS_INLINE_INLINE void prefetch_l1(const void* ptr) noexcept {
303#ifdef NEFORCE_SIMD_SSE2
304 _mm_prefetch(static_cast<const char*>(ptr), _MM_HINT_T0);
305#elif defined(NEFORCE_SIMD_NEON)
306 __builtin_prefetch(ptr, 0, 3);
307#else
308 (void) ptr;
309#endif
310}
311
316NEFORCE_ALWAYS_INLINE_INLINE void prefetch_l2(const void* ptr) noexcept {
317#ifdef NEFORCE_SIMD_SSE2
318 _mm_prefetch(static_cast<const char*>(ptr), _MM_HINT_T1);
319#elif defined(NEFORCE_SIMD_NEON)
320 __builtin_prefetch(ptr, 0, 2);
321#else
322 (void) ptr;
323#endif
324}
325
331NEFORCE_ALWAYS_INLINE_INLINE void prefetch_nta(const void* ptr) noexcept {
332#ifdef NEFORCE_SIMD_SSE2
333 _mm_prefetch(static_cast<const char*>(ptr), _MM_HINT_NTA);
334#elif defined(NEFORCE_SIMD_NEON)
335 __builtin_prefetch(ptr, 0, 0);
336#else
337 (void) ptr;
338#endif
339}
340 // SIMD
342
343NEFORCE_END_SIMD__
344NEFORCE_END_NAMESPACE__
345#endif // NEFORCE_CORE_SIMD_MEMORY_HPP__
unsigned char byte_t
字节类型,定义为无符号字符
unsigned char uint8_t
8位无符号整数类型
void store_aligned(void *ptr, vec128_t v) noexcept
对齐存储 128-bit 向量
::__m128i vec128_t
128-bit 整型向量(16×i8 / 8×i16 / 4×i32 / 2×i64)
::__m128 vec128f_t
128-bit 单精度浮点向量(4×f32)
::__m128d vec128d_t
128-bit 双精度浮点向量(2×f64)
::__m256i vec256_t
256-bit 整型向量(32×i8 / 16×i16 / 8×i32 / 4×i64,需 AVX2)
vec128_t loadu_si128(const void *ptr) noexcept
非对齐加载 128-bit 向量
void storeu_si256(void *ptr, vec256_t v) noexcept
非对齐存储 256-bit 向量
::__m512i vec512_t
512-bit 整型向量(64×i8 / 32×i16 / 16×i32 / 8×i64)
void prefetch_l1(const void *ptr) noexcept
预取数据到 L1 缓存以供读取
vec128_t load_aligned(const void *ptr) noexcept
对齐加载 128-bit 向量
void store_stream512(void *ptr, vec512_t v) noexcept
流式存储 512-bit 向量,绕过缓存
void storeu_si128(void *ptr, vec128_t v) noexcept
非对齐存储 128-bit 向量
void storeu_si512(void *ptr, vec512_t v) noexcept
非对齐存储 512-bit 向量
vec256_t loadu_si256(const void *ptr) noexcept
非对齐加载 256-bit 向量
void prefetch_write(const void *ptr) noexcept
预取数据到所有缓存层级以供写入
vec512_t loadu_si512(const void *ptr) noexcept
非对齐加载 512-bit 向量
vec128f_t loadu_ps(const void *ptr) noexcept
非对齐加载单精度浮点向量(128-bit)
vec128d_t loadu_pd(const void *ptr) noexcept
非对齐加载双精度浮点向量(128-bit)
void prefetch_nta(const void *ptr) noexcept
预取数据到缓存槽
vec128_t load_stream(const void *ptr) noexcept
流式加载 128-bit 向量
void store_stream256(void *ptr, vec256_t v) noexcept
流式存储 256-bit 向量,绕过缓存
void prefetch_l2(const void *ptr) noexcept
预取数据到 L2 缓存
void store_stream(void *ptr, vec128_t v) noexcept
流式存储 128-bit 向量,绕过缓存
void prefetch_read(const void *ptr) noexcept
预取数据到所有缓存层级以供读取
SIMD 向量类型定义