我有一个简单的单刀低通滤波器(用于参数平滑),可以通过以下公式解释:
y[n] = (1-a) * y[n-1] + a * x[n]
如何在ARM Neon上有效地矢量化这种情况 - 使用内在函数?可能吗? 问题是每次计算都需要先前的结果。
答案 0 :(得分:2)
假设您一次执行向量运算M
个元素(我认为NEON是128位宽,因此这将是M=4
32位元素),您可以通过a展开差分方程对于简单的单极滤波器,很容易M
因子。假设您已经计算了最多y[n]
的所有输出。然后,您可以按如下方式计算接下来的四个:
y[n+1] = (1-a)*y[n] + a*x[n+1]
y[n+2] = (1-a)*y[n+1] + a*x[n+2] = (1-a)*((1-a)*y[n] + a*x[n+1]) + a*x[n+2]
= (1-a)^2*y[n] + a*(1-a)*x[n+1] + a*x[n+2]
...
通常,您可以将y[n+k]
写为:
y[n+k] = (1-a)^2*y[n] + sum_{i=1}^k a*(1-a)^{k-i}*x[n+i]
我知道上面的内容很难阅读(也许我们可以将这个问题迁移到Signal Processing,我可以在LaTeX中重新排版)。但是,给定初始条件y[n]
(假设是先前计算的最后一个输出
矢量化迭代),您可以并行计算下一个M
输出,因为展开的滤波器的其余部分具有类似FIR的结构。
这种方法有一些注意事项:如果M
变大,那么你最终将一堆数字相乘,以便为展开的滤波器获得有效的FIR系数。根据您的数字格式和a
的值,这可能会产生数值精度影响。此外,您使用此方法无法获得M
- 倍的加速:您最终计算y[n+k]
的数量等于k
- 点击FIR滤波器。虽然您并行计算M
个输出,但是您必须执行k
乘法累加运算而不是简单的一阶递归实现,这会减少向量化的一些好处。
答案 1 :(得分:0)
如果您要将多个信号应用于同一过滤器,则只能对此进行矢量化,例如:如果它是立体声音频信号,那么您可以并行处理左右声道。并行的四个或八个通道显然会更好。
答案 2 :(得分:0)
通常,您只能向量化完全独立的计算集。但是在你的IIR低通中,每个输出都依赖于另一个(除了第一个),因此无法进行矢量化。
如果您的变量“a”足够大,使得(1-a)^ n快速衰减到低于您想要的本底噪声或允许误差,您可以用您的IIR替换短FIR滤波器近似值,并将该卷积矢量化。但那可能不会更快。
答案 3 :(得分:0)
如何将方程式扩展为4步并使用矩阵乘法? a是常数,因此可以预先计算一个矩阵