我有一个简单的单极点低通滤波器(用于参数平滑),可以用以下公式解释:
y[n] = (1-a) * y[n-1] + a * x[n]
如何使用内在函数在ARM Neon上有效地矢量化这种情况?可能吗?
问题在于每个计算都需要一个先前的结果。
最佳答案
假设您一次执行向量运算M
元素(我认为NEON的宽度为128位,因此将为M=4
32位元素),则可以很容易地将差异方程展开为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
乘加运算而不是简单的一阶递归实现这一事实削弱了矢量化的某些好处。关于arm - ARM NEON简单低通滤波器矢量化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8748923/