我正在尝试将无符号短数组转换为__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.
怎么了?有人可以帮帮我吗?
答案 0 :(得分:11)
注意数据调整。
当您取消引用__m128i*
或任何其他SSE类型时,指针需要与16个字节对齐。但是,x
和y
不能保证与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
,甚至不需要通过指针引用。