自动矢量化感兴趣区域(作物)

时间:2012-09-18 12:46:46

标签: c++ gcc crop vectorization roi

我有一个库,它有一些图像处理算法,包括感兴趣区域(裁剪)算法。使用GCC进行编译时,自动矢量化器会加速大量代码,但会降低Crop算法的性能。是否有一种标记某个循环的方法可以被矢量化器忽略,或者是否有更好的方法来构造代码以获得更好的性能?

for (RowIndex=0;RowIndex<Destination.GetRows();++RowIndex)
{
    rowOffsetS = ((OriginY + RowIndex) * SizeX) + OriginX;
    rowOffsetD = (RowIndex * Destination.GetColumns());
    for (ColumnIndex=0;ColumnIndex<Destination.GetColumns();++ColumnIndex)
    {
        BufferSPtr=BufferS + rowOffsetS + ColumnIndex;
        BufferDPtr=BufferD + rowOffsetD + ColumnIndex;
        *BufferDPtr=*BufferSPtr;
    }
}

其中 SizeX是源的宽度 OriginX是感兴趣区域的左侧 OriginY是感兴趣区域的顶端

1 个答案:

答案 0 :(得分:0)

我没有找到任何关于更改循环的优化标志的内容,但是根据文档,您可以在函数上使用属性optimize(查看herehere)要覆盖该函数的优化设置,如下所示:

void foo() __attribute__((optimize("O2", "inline-functions")))

如果您想为多个功能更改它,可以使用#pragma GCC optimize为所有后续功能(look here)设置它。

因此,您应该能够使用不同的优化标志集编译包含裁剪的函数,省略自动向量化。这样做的缺点就是硬编码该函数的编译标志,但这是我找到的最好的。

关于重组以获得更好的表现,我想到在评论中已经提到的两点(假设范围不能重叠):

  • 将指针声明为__restrict,告诉编译器它们没有别名(一个指针所指向的区域不会被函数内的任何其他方式访问)。指针别名的可能性是优化器的主要障碍,因为如果它不知道写入BufferD是否会改变BufferS的内容,它就不能轻易地重新排序访问。

  • 通过调用copy来替换内部循环:

    std::copy(BufferS + rowOffsetS, BufferS + rowOffsetS + Destination.GetColumns(), BufferD + rowOffsetD);
    

    copy函数可能已经过很好的优化(可能会将参数转发给memmove),这样可以使代码更快,同时也可以缩短代码(总是加分)。