GLSL可以执行递归公式计算吗?或者我怎样才能加快这个公式

时间:2015-01-10 03:19:11

标签: ios objective-c algorithm opengl-es glsl

我想在我的iOS App中实现这个公式。有没有办法使用GLSL加速这个公式。或者我可以使用mental或其他东西加速这个公式吗?

for (k = 0; k < imageSize; k++) {
    imageOut[k] = imageOut[k-1] * a + imageIn[k] * b;
}

OpenCL不可用。

2 个答案:

答案 0 :(得分:3)

这是一个经典的IIR过滤器,数据依赖性在将其转换为SIMD代码时会产生问题。这意味着您无法将操作作为简单的变换反馈或渲染到纹理操作。换句话说,GPU被设计为并行处理大量数据,但是您的公式会强制连续计算输出(您无法先计算out[k]来计算out[k-1]

我看到两种优化方法:

不幸的是,没有简单的GLSL翻译。也许你可以用Metal而不是NEON,我不确定。

答案 1 :(得分:2)

正如迪特里希·埃普已经指出的那样,你所拥有的是一个IIR滤波器。现在在计算机上没有“无限”这样的东西,你总是受到数字精度,内存,可用计算时间等的限制 - 即使你无限期地执行那个循环,由于你的典型数字代表的精度有限你很早就会发现任何有意义的事情来解决错误。

因此,请诚实地说明并使用非常长的响应时间调用FIR滤波器。那些可以并行化吗?是的,他们可以,但为此我们必须离开时域并从频域查看它。

假设您可以将对系统(=滤波器)的响应建模为所有可能的信号,然后根据信号“回放”该响应,为您提供所需的输出。在频域中,响应于覆盖所有频率的宽带信号,该频域将是系统的“记录”。但那个信号只是一个简单的冲动。这就是FIR和IIR这两个术语从中获取中间 I 的地方。

通过卷积将系统的脉冲响应应用于任意信号,可以为您提供系统对信号本身的响应。然而,在时域中计算卷积与将信号的傅里叶变换乘以脉冲响应的傅里叶变换并将结果转换回来相同,即

s * r = F^-1(F(s) · F(r))

傅立叶变换是可以很好地并行化的事情之一,GPU非常擅长。

现在有基于GLSL的傅里叶变换代码,但通常这些代码是用OpenCL或CUDA编写的,以便在GPU上运行。

无论如何,这是给你的食谱:

确定您的IIR与FIR无法区分的截止k。确定脉冲响应的傅里叶变换(=复合光谱响应,CSR)。傅里叶变换信号(=图像)与CSR相乘并转换回来。