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