考虑使用英特尔SSE内在函数的代码片段,如下所示:
void foo(double* in1ptr, double* in2ptr)
{
double result[8];
/* .. stuff .. */
__m128d in1 = _mm_loadu_pd(in1ptr);
__m128d in2 = _mm_loadu_pd(in2ptr);
__m128d* resptr = (__m128d*)(&result[4]); <----------
*resptr = __mm_add_pd(in1,in2);
/* .. stuff .. */
}
在指示的行中 - 声明resptr
指向结果数组中索引4处的位置 -
1)这适用于gcc
,但这是正确的做事方式吗?
2)这里的对齐期望是什么,我可以创建resptr
指针指向任意内存位置,然后将SSE操作的结果存储在该内存位置吗?
答案 0 :(得分:1)
加载/存储内在函数存在以向编译器传达对齐保证或缺少对齐保证。如果您的数据是16B对齐或32B对齐,则您不需要它们。
只是转换为(__m128d*)
遵循通常的C语义,暗示__m128d
有足够的对齐。 (编译器使用movapd
而非movupd
,如果地址未对齐,则会在运行时出错。
在这种情况下,您没有采取任何措施来确保对齐。幸运的是,您的本地阵列是16B对齐的。如果您使用alignas(16) double result[8];
,则该代码将是安全的。
对于未对齐的商店,请使用_mm_storeu_pd
。另请参阅x86标记wiki。