5

I'm trying to cast unsigned short array to __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];

First casting work fine, but the second one - not. I've got:

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

What's wrong? Can somebody help me?

4

2 回答 2

12

注意你的数据对齐。

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

强制对齐取决于编译器。

视觉 C++

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

海合会

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

或者,您可以使用未对齐的负载(尽管可能会降低性能):

__m128i n = __mm_loadu_si128((__m128i*) &y[0]);
__m128i m = __mm_loadu_si128((__m128i*) &x[0]);
于 2012-07-20T01:08:54.777 回答
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} };

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

于 2012-07-20T06:55:14.577 回答