1

我有一个库,其中包含一些图像处理算法,包括感兴趣区域(裁剪)算法。使用 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的顶部

4

1 回答 1

0

我还没有找到任何关于更改循环优化标志的信息,但是根据文档,您可以在函数上使用属性optimize(查看此处此处)来覆盖该函数的优化设置,有点像这样:

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

如果您想为多个功能更改它,您可以使用#pragma GCC optimize为以下所有功能设置它(看这里)。

因此,您应该能够使用一组不同的优化标志编译包含裁剪的函数,省略自动矢量化。这具有硬编码该函数的编译标志的缺点,但这是我发现的最好的。

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

  • 将指针声明为__restrict告诉编译器它们没有别名(一个指针指向的区域不会被函数内的任何其他方式访问)。指针别名的可能性是优化器的主要绊脚石,因为如果它不知道写入是否BufferD会更改BufferS.

  • 用复制调用替换内部循环:

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

    copy函数可能已经得到了很好的优化(可能会将参数转发到memmove),因此这可能会使您的代码更快,同时也使您的代码更短(总是一个加号)。

于 2012-09-18T13:44:11.070 回答