在施放到__m128i期间出现奇怪的错误

时间:2012-07-20 01:06:27

标签: c sse sse2

我正在尝试将无符号短数组转换为__m128i

const unsigned short x[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
const unsigned short y[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

__m128i n = *(__m128i*) &y[0];
__m128i m = *(__m128i*) &x[0];

第一次施法工作正常,但第二次施工 - 没有。我有:

Unhandled exception at 0x013839ee in sse2_test.exe: 0xC0000005: Access violation reading location 0xffffffff.

怎么了?有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:11)

注意数据调整。

当您取消引用__m128i*或任何其他SSE类型时,指针需要与16个字节对齐。但是,xy不能保证与16个字节对齐。

执行对齐取决于编译器。

Visual C ++

__declspec(align(16)) const unsigned short x[] = ...

<强> GCC

const unsigned short x[] __attribute__((aligned(16))) = ...

或者,您可以使用未对齐的加载(在可能的性能损失下abeit):

__m128i n = __mm_loadu_si128((__m128i*) &y[0]);
__m128i m = __mm_loadu_si128((__m128i*) &x[0]);

答案 1 :(得分:1)

你不应该盲目地将一个指针类型转换为另一个指针类型,因为Mystical说你应该期待对齐问题。 C11有_Alignas,其他编译器也扩展到C99或C89做同样的事情。

官方,以及我发现最清楚的方法来解决C99这样的事情就是创建一个union

union combine {
  unsigned short x[sizeof(__m128i)/sizeof(unsigned short)];
  __m128i y;
}

union combine X = { .x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} };

这样的union保证为其所有成员正确对齐。 现在您可以轻松使用X.y,甚至不需要通过指针引用。