_mm_shuffle_epi8上的常规保护错误

时间:2014-02-07 12:53:43

标签: c intrinsics

我在C中有一个带有原型void f(__m128i *x)的函数。在此函数中,我现在调用_mm_shuffle_epi8(*x, MASK),其中MASK是常量__m128i类型。当我运行代码时,我得到一个分段错误,Valgrind发现它实际上是在这一行上发生的一般保护错误。

这可能是什么原因,我该如何解决这个问题?

小工作示例:

#include <wmmintrin.h>
#include <smmintrin.h>

#define BSWAP_MASK              _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
#define ALIGN(n)                __attribute__ ((aligned(n)))

static inline void g(const unsigned char *in, unsigned char *out) {
    __m128i tmp = _mm_load_si128 ((__m128i*)in);
    _mm_store_si128((__m128i*)out, tmp);
}

void f(__m128i *res) {
    g((unsigned char*)&res, (unsigned char*)&res);
    *res = _mm_shuffle_epi8(*res, BSWAP_MASK);
}

int main() {
    ALIGN(16) __m128i x = _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
    f(&x);
}

1 个答案:

答案 0 :(得分:1)

如怀疑的那样,你有对齐问题。

如果没有正确对齐数据,或者使用函数加载和存储未对齐的地址,结果就会崩溃。

如果您想使用未对齐的地址,那么这可以解决问题:

static inline void g(const unsigned char *in, unsigned char *out) {
    //__m128i tmp = _mm_load_si128 ((__m128i*)in);
    __m128i tmp = _mm_loadu_si128 ((__m128i*)in);
    //_mm_store_si128((__m128i*)out, tmp);
    _mm_storeu_si128((__m128i*)out, tmp);
}

至于链接器未能使该变量正确对齐的原因,请参阅Are stack variables aligned by the GCC __attribute__((aligned(x)))?及其中的答案。

如果您使用的是Linux,则可以使用posix_memalign()函数。