1次の再帰フィルターの計算をベクトル化するにはどうすればよいですか?


9

次の式で説明できる単純な単極ローパスフィルター(パラメーター平滑化用)があります。

y[]=1ay[1]+aバツ[]

私が使用しているアーキテクチャは、複数のベクトル化された計算を並行して実行できる単一命令、複数データ(SIMD)命令にアクセスできます。この機能を利用したいのですが、このような再帰的フィルターでそれを行う方法がわかりません。問題は、すべての計算が以前の結果を必要とすることです。


これが「オフトピック」としてクローズされた理由を誰かが説明してもらえますか?
ポールR

質問はこことスタックオーバーフローの間で重複しています。元の質問では、ARM NEON拡張を使用してそれを実装する方法を具体的に尋ねました。質問は両方のサイトに存在します。ここでは、並列処理を利用するための問題の構造化に関する理論的な議論を行うために編集しました。
Jason R

@PaulR昨日ここに移行するように依頼しましたが、フォノンはSOではなく、SOに属していると強く感じました。認めます。ARMNEONについては特に知りません。彼はおそらく正しいので、私は彼の判断を尊重します。このメタ質問を参照してください。私の削除された回答は基本的に私がジェイソンRに同意し、ユーザーは移行のためにそのような質問にフラグを立てるべきであると述べました
Lorem Ipsum

1
説明の両方に感謝します-私は自分のプロファイルを上げるためにここでDSP関連の質問を移行するために最善を尽くしてきたので、この質問がクローズされたときにこれが正しいことかどうか心配でした-より一般的な形で再びオープンしたことをうれしく思います。
ポールR

回答:


7

一度に要素のベクトル演算を実行すると仮定すると、単純な単極フィルターの場合、差分方程式をMの因数でかなり簡単に展開できます。y [ n ]までのすべての出力を既に計算していると仮定します。その後、次のように後続の値を計算できます 。y [ n + 1 ]MMy[]

y[n+1]=(1a)y[n]+ax[n+1]y[n+2]=(1a)y[+1]+aバツ[+2]=1a1ay[]+aバツ[+1]+aバツ[+2]=1a2y[]+a1aバツ[+1]+aバツ[+2]

一般に、は次のように書くことができます。y[+k]

y[+k]=1aky[]+Σ=1ka1akバツ[+]

各サンプルインデックス、これはk + 1タップのFIRフィルターのように見えます。1つのタップは最後のフィルター出力y [ n ]を乗算し、他のkタップはフィルター入力x [ n + 1 ] 、を乗算しますx [ n + k ]。これらすべてのタップに使用される係数を事前に計算できるため、再帰型フィルターをM M + 1に展開できます。+kk+1y[]kバツ[+1]バツ[+k]M M+1-タップ非並列再帰フィルター(これらのフィルターは出力サンプル計算します)、M個の出力サンプルごとにフィードバック項を更新します。したがって、初期条件y [ n ](前回のベクトル化反復で計算された最後の出力であると想定)が与えられた場合、次のM個の出力を並列で計算できます。y[+1]y[+M]My[]M

このアプローチにはいくつかの注意点があります。

  • 場合は大きくなると、あなたは広げられたフィルタのための効果的なFIR係数を得るために一緒に数字の束を乗じてしまいます。数値形式との値によって、これは数値の精度に影響を与える可能性があります。Ma

  • また、このアプローチでは倍のスピードアップは得られません。結局、y [ n + k ]を計算して、kタップのFIRフィルターに相当するものを計算します。M個の出力を並列で計算していますが、単純な1次の再帰的な実装ではなくk回の積和演算(MAC)演算を実行する必要があるという事実は、ベクトル化の利点の一部を減少させます。非ベクトル化アプローチでは、出力ごとに2つのMACを使用するため、M個の出力を計算するには2 M回の演算が必要です。ベクトル化されたスキームは、M個の出力を一度に計算するため、M +My[+k]kMk2MMMプロセス中のMAC。したがって、操作の削減は Mの関数として次のように表すことができます。M+1M

    R=M+12M=121+1M

    MM=4M=8y[]y[1]。この効果は明ら​​かにプラットフォームに大きく依存します。


3

一般に、完全に独立した計算セットのみをベクトル化できます。しかし、IIRローパスでは、すべての出力が別の出力に依存しているため(1番目を除く)、ベクトル化は不可能です。

変数 "a"が十分大きく(1-a)^ nが目的のノイズフロアまたは許容誤差を下回るまで急速に減衰する場合は、IIRを短いFIRフィルター近似に置き換え、代わりにその畳み込みをベクトル化できます。しかし、それは速くなる可能性は低いです。


2

これを効果的にベクトル化できるのは、同じフィルターを適用したい信号が複数ある場合のみです。たとえば、ステレオオーディオ信号の場合、左右のチャネルを並行して処理できます。並列の4または8チャネルのほうが明らかに優れています。


0

方程式を4ステップに拡張し、行列乗算を使用するのはどうでしょうか。aは定数なので、1つの行列を事前に計算できます


0

複数の独立したストリームのフィルタリングを並列にベクトル化することが最も効率的です。

単一の長いストリームがある場合は、ストリームをいくつかの重複するセクションに分割し、独立したストリームであるかのようにこれらをフィルタリングすることもできます。

各ストリームの最初の数サンプルが正しくないため、オーバーラップが必要です。破棄する必要があるサンプルの量は、aの値と必要な精度によって異なります。結果がeps * max(| x [i] |)に正確になるように、(1 / a)(1-a)** n <epsであるn個のサンプルを破棄する必要があります。

たとえば、a = 0.1の場合、128サンプルでは、​​(1 / a)(1-a)^ nによって引き起こされるエラーは16ビット整数のLSBよりも小さくなりますが、a = 0.9の場合は破棄するだけで済みます。約6サンプル。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.