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

alignment requirements when storing the result of SSE operations

考虑使用英特尔 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*) 遵循暗示 __m128d 具有足够对齐的通常 C 语义。 (编译器使用 movapd 而不是 movupd,如果地址未对齐,将在 运行 时出错。

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

对于未对齐的商店,使用 _mm_storeu_pd。另请参阅 标签 wiki。