相关疑难解决方法(0)

如何实现"_mm_storeu_epi64"没有别名问题?

(注意:虽然这个问题是关于"存储"的,但"加载"情况具有相同的问题并且是完全对称的.)

SSE内在函数提供_mm_storeu_pd具有以下签名的函数:

void _mm_storeu_pd (double *p, __m128d a);
Run Code Online (Sandbox Code Playgroud)

所以,如果我有两个双精度矢量,并且我想将它存储到两个双精度数组中,我可以使用这个内在函数.

但是,我的矢量不是两个双打; 它是两个64位整数,我想将它存储到两个64位整数的数组中.也就是说,我想要一个具有以下签名的函数:

void _mm_storeu_epi64 (int64_t *p, __m128i a);
Run Code Online (Sandbox Code Playgroud)

但内在函数没有提供这样的功能.他们最接近的是_mm_storeu_si128:

void _mm_storeu_si128 (__m128i *p, __m128i a);
Run Code Online (Sandbox Code Playgroud)

问题是这个函数需要一个指针__m128i,而我的数组是一个数组int64_t.通过错误类型的指针写入对象违反了严格的别名,并且肯定是未定义的行为.我担心我的编译器现在或将来会重新排序或以其他方式优化存储,从而以奇怪的方式破坏我的程序.

要清楚,我想要的是一个我可以这样调用的函数:

__m128i v = _mm_set_epi64x(2,1);
int64_t ra[2];
_mm_storeu_epi64(&ra[0], v); // does not exist, so I want to implement it
Run Code Online (Sandbox Code Playgroud)

以下是创建此类功能的六次尝试.

尝试#1

void _mm_storeu_epi64(int64_t *p, __m128i a) {
    _mm_storeu_si128(reinterpret_cast<__m128i *>(p), a);
}
Run Code Online (Sandbox Code Playgroud)

这似乎有我担心的严格别名问题.

尝试#2

void _mm_storeu_epi64(int64_t *p, __m128i a) {
    _mm_storeu_si128(static_cast<__m128i *>(static_cast<void *>(p)), a);
}
Run Code Online (Sandbox Code Playgroud)

一般来说可能更好 …

c++ sse strict-aliasing intrinsics

17
推荐指数
1
解决办法
1506
查看次数

标签 统计

c++ ×1

intrinsics ×1

sse ×1

strict-aliasing ×1