存储SSE操作结果时的对齐要求

alignment requirements when storing the result of SSE operations

本文关键字:对齐 SSE 操作 结果 存储      更新时间:2023-10-16

考虑使用英特尔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操作的结果吗?

load/store内部函数的存在是为了向编译器传达对齐保证或缺少对齐保证。如果您的数据是16B对齐或32B对齐的,则不需要它们。

仅转换为(__m128d*)遵循通常的C语义,即暗示__m128d具有足够的对齐。(编译器使用movapd而不是movupd,如果地址不对齐,则会在运行时出错)。

在这种情况下,您没有采取任何措施来确保对齐。幸运的是,你的本地数组是16B对齐的。如果您使用alignas(16) double result[8];,该代码将是安全的。

对于未对齐的存储,请使用_mm_storeu_pd。另请参阅x86标记wiki。