所以我试图做一个类似
的数组操作for (int i=0;i++i<32)
{
output[offset+i] += input[i];
}
其中output
和input
是float
个数组(由于malloc
而对齐16个字节)。但是,我无法保证offset%4=0
。我想知道如何解决这些对齐问题。
我喜欢
while (offset+c %4 != 0)
{
c++;
output[offset+c] += input[c];
}
后跟一个对齐的循环 - 显然这不起作用,因为我们现在需要对input
进行未对齐的访问。
有没有办法对我的原始循环进行矢量化?
答案 0 :(得分:5)
将评论移至答案:
存在未对齐内存访问的SSE指令。可以通过以下内在函数访问它们:
_mm_loadu_ps()
- documentation _mm_storeu_ps()
- documentation 和所有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
}