如何在没有对齐数组的情况下进行对齐添加

时间:2012-04-24 02:55:07

标签: c sse simd

所以我试图做一个类似

的数组操作
for (int i=0;i++i<32)
{
    output[offset+i] += input[i];
}

其中outputinputfloat个数组(由于malloc而对齐16个字节)。但是,我无法保证offset%4=0。我想知道如何解决这些对齐问题。

我喜欢

while (offset+c %4 != 0)
{
    c++;
    output[offset+c] += input[c];
}

后跟一个对齐的循环 - 显然这不起作用,因为我们现在需要对input进行未对齐的访问。

有没有办法对我的原始循环进行矢量化?

1 个答案:

答案 0 :(得分:5)

将评论移至答案:

存在未对齐内存访问的SSE指令。可以通过以下内在函数访问它们:

和所有double和整数类型类似。

因此,如果你不能保证对齐,那么这是一个简单的方法。如果可能,理想的解决方案是从一开始就对齐阵列,以便完全避免这个问题。

对于未对齐的访问,仍会存在性能损失,但除非您采用非常混乱的移位/随机黑客(例如_mm_alignr_epi8()),否则它们是不可避免的。

使用_mm_loadu_ps_mm_storeu_ps的代码 - 这实际上比gcc本身慢了50%

for (int j=0;j<8;j++)
{
    float* out = &output[offset+j*4];
    __m128 in = ((__m128*)input)[j]; //this is aligned so no need for _mm_loadu_ps
    __m128 res  = _mm_add_ps(in,_mm_loadu_ps(out)); //add values 
    _mm_storeu_ps(out,res); //store result
}