次の式で説明できる単純な単極ローパス フィルター (パラメーターの平滑化用) があります。
y[n] = (1-a) * y[n-1] + a * x[n]
ARM Neon でこのケースを効果的にベクトル化する方法 - 組み込み関数を使用しますか? 出来ますか?問題は、すべての計算が前の結果を必要とすることです。
次の式で説明できる単純な単極ローパス フィルター (パラメーターの平滑化用) があります。
y[n] = (1-a) * y[n-1] + a * x[n]
ARM Neon でこのケースを効果的にベクトル化する方法 - 組み込み関数を使用しますか? 出来ますか?問題は、すべての計算が前の結果を必要とすることです。
一度にベクトル演算要素を実行すると仮定するとM
(NEON は 128 ビット幅なので、M=4
32 ビット要素になると思います)、M
単純な単極フィルターの係数で差分方程式を非常に簡単に展開できます。までのすべての出力をすでに計算していると仮定しますy[n]
。次に、次の 4 つを次のように計算できます。
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 でタイプセットし直すことができます)。ただし、初期条件(前のベクトル化された反復で計算された最後の出力であると想定されます) が与えられると、展開されたフィルターの残りの部分が FIR のような構造を持つため、y[n]
次の出力を並列に計算できます。M
このアプローチにはいくつかの注意点があります。 ifM
が大きくなると、展開されたフィルターの有効な FIR 係数を取得するために、多数の数値を乗算することになります。数値形式と の値によってはa
、数値精度に影響する可能性があります。また、M
このアプローチでは 2 倍の高速化は得られません。最終的には、 -tap FIR フィルターy[n+k]
に相当するものを計算することになります。出力を並列にk
計算していますが、単純な 1 次再帰的な実装ではなく積和演算を実行する必要があるという事実により、ベクトル化の利点がいくらか失われます。M
k
方程式を 4 ステップに拡張し、行列の乗算を使用するのはどうですか? a は一定であるため、1 つの行列を事前に計算することができます
これを実際にベクトル化できるのは、同じフィルターを適用したい信号が複数ある場合のみです。たとえば、ステレオ オーディオ信号の場合、左右のチャンネルを並行して処理できます。4 つまたは 8 つのチャネルを並列に接続すると、明らかにさらに優れたものになります。
一般に、完全に独立した計算セットのみをベクトル化できます。しかし、IIR ローパスでは、すべての出力が別の出力に依存しているため (最初の出力を除く)、ベクトル化はできません。
変数 "a" が十分に大きく、(1-a)^n が目的のノイズ フロアまたは許容誤差を下回るまで急速に減衰する場合は、IIR の代わりに短い FIR フィルター近似を使用し、代わりにその畳み込みをベクトル化することができます。しかし、それはおそらく速くなりません。