1#ifndef NEFORCE_CORE_SIMD_MEMORY_HPP__
2#define NEFORCE_CORE_SIMD_MEMORY_HPP__
12NEFORCE_BEGIN_NAMESPACE__
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));
33 const auto* src =
static_cast<const byte_t*
>(ptr);
34 for (
int i = 0; i < 16; ++i) {
35 result.data[i] = src[i];
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));
53 const auto* src =
static_cast<const byte_t*
>(ptr);
54 for (
int i = 0; i < 16; ++i) {
55 result.data[i] = src[i];
67#if defined(NEFORCE_SIMD_AVX)
68 return ::_mm256_loadu_si256(
static_cast<const vec256_t*
>(ptr));
71 const auto* src =
static_cast<const byte_t*
>(ptr);
72 for (
int i = 0; i < 32; ++i) {
73 result.data[i] = src[i];
85#ifdef NEFORCE_SIMD_AVX512F
86 return ::_mm512_loadu_si512(ptr);
89 const auto* src =
static_cast<const byte_t*
>(ptr);
90 for (
int i = 0; i < 64; ++i) {
91 result.data[i] = src[i];
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));
109 const auto* src =
static_cast<const float*
>(ptr);
110 for (
int i = 0; i < 4; ++i) {
111 result.data[i] = src[i];
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));
129 const auto* src =
static_cast<const double*
>(ptr);
130 for (
int i = 0; i < 2; ++i) {
131 result.data[i] = src[i];
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);
149 auto* dst =
static_cast<byte_t*
>(ptr);
150 for (
int i = 0; i < 16; ++i) {
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);
167 auto* dst =
static_cast<byte_t*
>(ptr);
168 for (
int i = 0; i < 16; ++i) {
180#if defined(NEFORCE_SIMD_AVX)
181 ::_mm256_storeu_si256(
static_cast<vec256_t*
>(ptr), v);
183 auto* dst =
static_cast<byte_t*
>(ptr);
184 for (
int i = 0; i < 32; ++i) {
196#ifdef NEFORCE_SIMD_AVX512F
197 ::_mm512_storeu_si512(ptr, v);
199 auto* dst =
static_cast<byte_t*
>(ptr);
200 for (
int i = 0; i < 64; ++i) {
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);
219 auto* dst =
static_cast<byte_t*
>(ptr);
220 for (
int i = 0; i < 16; ++i) {
233#if defined(NEFORCE_SIMD_AVX)
234 ::_mm256_stream_si256(
static_cast<vec256_t*
>(ptr), v);
236 auto* dst =
static_cast<byte_t*
>(ptr);
237 for (
int i = 0; i < 32; ++i) {
250#ifdef NEFORCE_SIMD_AVX512F
251 ::_mm512_stream_si512(ptr, v);
253 auto* dst =
static_cast<byte_t*
>(ptr);
254 for (
int i = 0; i < 64; ++i) {
267#if defined(NEFORCE_SIMD_SSE4_1)
268 return ::_mm_stream_load_si128(
const_cast<vec128_t*
>(
static_cast<const vec128_t*
>(ptr)));
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);
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);
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);
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);
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);
344NEFORCE_END_NAMESPACE__
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
预取数据到所有缓存层级以供读取