_mm_shuffle_epi8 上的一般保护故障

Posted

技术标签:

【中文标题】_mm_shuffle_epi8 上的一般保护故障【英文标题】:General protection fault on _mm_shuffle_epi8 【发布时间】:2014-02-07 12:53:42 【问题描述】:

我在 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);

【问题讨论】:

内存在x 16字​​节对齐吗? 是16字节对齐的 如果您可以发布一个小的、可重复的示例,我们可以用来复制,我们会提供帮助。 是的,我正在尝试,但我的小例子不会重现坏东西.. 如果(x)指向单个__m128而不是一个数组,那么按值传递,按值返回不是更容易吗?可能使用 SSE 寄存器来传递参数和返回值,即使没有内联。 【参考方案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()函数。

【讨论】:

以上是关于_mm_shuffle_epi8 上的一般保护故障的主要内容,如果未能解决你的问题,请参考以下文章

iOS 8 上的 snapshotViewAfterScreenUpdates 故障

分布式系统服务保护

如何对 Tomcat 8 上的连接性能进行故障排除?

(转)主从复制_笔记

9.8.6恢复系统数据库

hiccup和Latch off