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



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

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

OpenCL 不可用。

这是一个经典的 IIR 滤波器,数据依赖关系在将其转换为 SIMD 代码时会导致问题。 这意味着您不能将操作作为简单的转换反馈或渲染到纹理操作来执行。 换句话说,GPU 旨在并行处理一堆数据,但您的公式强制串行计算输出(如果不先计算out[k-1],则无法计算out[k])。

我看到了两种优化方法:

  • 您可以在 CPU 上使用 SIMD。 对于 iOS,这意味着 ARM NEON。 请参阅使用 ARM NEON 优化 IIR 滤波器或使用 SIMD 扩展优化 IIR 滤波器等文章。

  • 您可以将滤波器重新设计为 FIR 滤波器,从而完全消除数据依赖性。

不幸的是,没有简单的翻译到GLSL。 也许你可以用金属代替霓虹灯,我不确定。

正如 Dietrich Epp 已经指出的那样,您那里有一个 IIR 滤波器。现在在计算机上没有"无限"这样的东西,你总是受到数字精度、内存、可用计算时间等的限制——即使你无限期地执行了那个循环,由于你的典型数字表示的精度有限,你会在很早的时候失去任何有意义的舍入误差。

因此,让我们诚实地调用响应时间很长的FIR滤波器。这些可以并行化吗?是的,他们可以,但为此我们必须离开时域并从频域来看它。

假设您可以根据所有可能的信号对系统(=filter)的响应进行建模,然后根据信号"回放"该响应,为您提供所需的输出。在频域中,这将是系统的"记录",以响应覆盖所有频率的宽带信号。但这个信号只是一个简单的冲动。这就是术语FIR和IIR的中间I的来源。

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

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

傅里叶变换是可以很好地并行化的东西之一,GPU 确实非常擅长。

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

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

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

最新更新