GLSL可以进行递归公式计算吗?或者我怎样才能加快这个公式
Can GLSL perform a recursion formula calculation? Or how can I speed up this formular
我想在我的 iOS 应用程序中实现这个公式。有什么方法可以使用 GLSL 来加速这个公式。或者我可以使用 mental 或其他东西来加速这个公式吗?
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。查看 Optimising IIR Filters Using ARM NEON or Parallelization of IIR Filters using SIMD Extensions.
等文章
您可以将滤波器重新设计为 FIR 滤波器,从而完全消除数据依赖性。
不幸的是,没有简单的 GLSL 翻译。也许你可以使用 Metal 而不是 NEON,我不确定。
正如 Dietrich Epp 已经指出的那样,您拥有的是一个 IIR 滤波器。现在在计算机上没有 "inifinite" 这样的东西,你总是受到数字精度、内存、可用计算时间等的限制——即使你无限地执行该循环,因为你的典型数字的精度有限表示你会很早就失去任何有意义的四舍五入错误。
所以让我们诚实一点,调用一个响应时间很长的 FIR 滤波器。那些可以并行化吗?是的,他们可以,但为此我们必须离开时域,从频域来看。
假设您可以对系统(=过滤器)对所有可能信号的响应建模,然后 "playing back" 基于信号的响应会为您提供所需的输出。在频域中,系统响应覆盖所有频率的宽带信号将是 "recording"。但那个信号只是一个简单的冲动。这就是术语 FIR 和 IIR 的中间 I 来源。
任何通过 卷积 将系统的脉冲响应应用于任意信号的方法都会为您提供系统对信号本身的响应。然而,计算时域卷积与将信号的傅里叶变换与脉冲响应的傅里叶变换相乘并将结果反变换回来是相同的,即
s * r = F^-1(F(s) · F(r))
傅里叶变换是可以很好地并行化的事物之一,而 GPU 确实非常擅长。
现在有基于 GLSL 的傅里叶变换代码,但通常这些代码是用 OpenCL 或 CUDA 编写的 运行 在 GPU 上。
无论如何,这是给你的食谱:
确定您的 IIR 与 FIR 无法区分的截止点 k
。确定脉冲响应的傅立叶变换(= 复谱响应,CSR)。傅里叶变换信号(=图像)与 CSR 相乘并变换回来。
我想在我的 iOS 应用程序中实现这个公式。有什么方法可以使用 GLSL 来加速这个公式。或者我可以使用 mental 或其他东西来加速这个公式吗?
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。查看 Optimising IIR Filters Using ARM NEON or Parallelization of IIR Filters using SIMD Extensions.
等文章
您可以将滤波器重新设计为 FIR 滤波器,从而完全消除数据依赖性。
不幸的是,没有简单的 GLSL 翻译。也许你可以使用 Metal 而不是 NEON,我不确定。
正如 Dietrich Epp 已经指出的那样,您拥有的是一个 IIR 滤波器。现在在计算机上没有 "inifinite" 这样的东西,你总是受到数字精度、内存、可用计算时间等的限制——即使你无限地执行该循环,因为你的典型数字的精度有限表示你会很早就失去任何有意义的四舍五入错误。
所以让我们诚实一点,调用一个响应时间很长的 FIR 滤波器。那些可以并行化吗?是的,他们可以,但为此我们必须离开时域,从频域来看。
假设您可以对系统(=过滤器)对所有可能信号的响应建模,然后 "playing back" 基于信号的响应会为您提供所需的输出。在频域中,系统响应覆盖所有频率的宽带信号将是 "recording"。但那个信号只是一个简单的冲动。这就是术语 FIR 和 IIR 的中间 I 来源。
任何通过 卷积 将系统的脉冲响应应用于任意信号的方法都会为您提供系统对信号本身的响应。然而,计算时域卷积与将信号的傅里叶变换与脉冲响应的傅里叶变换相乘并将结果反变换回来是相同的,即
s * r = F^-1(F(s) · F(r))
傅里叶变换是可以很好地并行化的事物之一,而 GPU 确实非常擅长。
现在有基于 GLSL 的傅里叶变换代码,但通常这些代码是用 OpenCL 或 CUDA 编写的 运行 在 GPU 上。
无论如何,这是给你的食谱:
确定您的 IIR 与 FIR 无法区分的截止点 k
。确定脉冲响应的傅立叶变换(= 复谱响应,CSR)。傅里叶变换信号(=图像)与 CSR 相乘并变换回来。