1

我对 GPU 编程和 C++ AMP 相当陌生。任何人都可以帮助制作通用优化的二维图像卷积滤波器吗?到目前为止,我的禁食版本如下所示。可以以某种方式通过平铺做得更好吗?这个版本运行起来比我的 CPU 实现要快得多,但我希望能做得更好。

void FIRFilterCore(array_view<const float, 2> src, array_view<float, 2> dst, array_view<const float, 2> kernel)
{
    int vertRadius = kernel.extent[0] / 2;
    int horzRadius = kernel.extent[1] / 2;

    parallel_for_each(src.extent, [=](index<2> idx) restrict(amp)
    {
        float sum = 0;
        if (idx[0] < vertRadius || idx[1] < horzRadius ||
            idx[0] >= src.extent[0] - vertRadius || idx[1] >= src.extent[1] - horzRadius)
        {
            // Handle borders by duplicating edges
            for (int dy = -vertRadius; dy <= vertRadius; dy++)
            {
                index<2> srcIdx(direct3d::clamp(idx[0] + dy, 0, src.extent[0] - 1), 0);
                index<2> kIdx(vertRadius + dy, 0);
                for (int dx = -horzRadius; dx <= horzRadius; dx++)
                {
                    srcIdx[1] = direct3d::clamp(idx[1] + dx, 0, src.extent[1] - 1);
                    sum += src[srcIdx] * kernel[kIdx];
                    kIdx[1]++;
                }
            }
        }
        else // Central part
        {
            for (int dy = -vertRadius; dy <= vertRadius; dy++)
            {
                index<2> srcIdx(idx[0] + dy, idx[1] - horzRadius);
                index<2> kIdx(vertRadius + dy, 0);
                for (int dx = -horzRadius; dx <= horzRadius; dx++)
                {                   
                    sum += src[srcIdx] * kernel[kIdx];
                    srcIdx[1]++;
                    kIdx[1]++;
                }
            }
        }
        dst[idx] = sum;
    });
}

绕过它的另一种方法当然是在傅里叶域中执行卷积,但我不确定只要滤波器与图像相比相当小(它没有边长是幂)它会执行顺便说一句)。

4

1 回答 1

1

您可以找到 Cartoonizer 算法的完整实现。它在 Codeplex 上实现了几个基于模板的算法。http://ampbook.codeplex.com/

这包括几个不同的实现。在编写示例的书中讨论了与它们相关的权衡。

对于最小帧处理器设置(1 个简化阶段和 1 边框宽度),没有足够的共享内存访问来利用平铺内存。通过比较在单个 GPU 上运行的 C++ AMP 简单模型 (4.9 ms) 和平铺模型 (4.2 ms) 的卡通化阶段所花费的时间,可以清楚地看到这一点。您会期望平铺实现执行得更快,但它是可比的。对于默认和最大帧处理器设置,平铺内存变得更有利,并且平铺模型处理器比简单模型处理器执行得更快。

这里有一个类似的问题:

在 C++Amp 中并行化的几个算术运算

我在那里发布了一些代码,显示了一个可变大小的过滤器。

于 2013-09-04T08:02:58.390 回答