次の式で説明できる単純な単極ローパスフィルター(パラメーター平滑化用)があります。
私が使用しているアーキテクチャは、複数のベクトル化された計算を並行して実行できる単一命令、複数データ(SIMD)命令にアクセスできます。この機能を利用したいのですが、このような再帰的フィルターでそれを行う方法がわかりません。問題は、すべての計算が以前の結果を必要とすることです。
次の式で説明できる単純な単極ローパスフィルター(パラメーター平滑化用)があります。
私が使用しているアーキテクチャは、複数のベクトル化された計算を並行して実行できる単一命令、複数データ(SIMD)命令にアクセスできます。この機能を利用したいのですが、このような再帰的フィルターでそれを行う方法がわかりません。問題は、すべての計算が以前の結果を必要とすることです。
回答:
一度に要素のベクトル演算を実行すると仮定すると、単純な単極フィルターの場合、差分方程式をMの因数でかなり簡単に展開できます。y [ n ]までのすべての出力を既に計算していると仮定します。その後、次のように後続の値を計算できます 。y [ n + 1 ]
一般に、は次のように書くことができます。
各サンプルインデックス、これはk + 1タップのFIRフィルターのように見えます。1つのタップは最後のフィルター出力y [ n ]を乗算し、他のkタップはフィルター入力x [ n + 1 ] 、… 、を乗算します。x [ n + k ]。これらすべてのタップに使用される係数を事前に計算できるため、再帰型フィルターをM M + 1に展開できます。 -タップ非並列再帰フィルター(これらのフィルターは出力サンプル計算します)、M個の出力サンプルごとにフィードバック項を更新します。したがって、初期条件y [ n ](前回のベクトル化反復で計算された最後の出力であると想定)が与えられた場合、次のM個の出力を並列で計算できます。
このアプローチにはいくつかの注意点があります。
場合は大きくなると、あなたは広げられたフィルタのための効果的なFIR係数を得るために一緒に数字の束を乗じてしまいます。数値形式との値によっては、これは数値の精度に影響を与える可能性があります。
また、このアプローチでは倍のスピードアップは得られません。結局、y [ n + k ]を計算して、kタップのFIRフィルターに相当するものを計算します。M個の出力を並列で計算していますが、単純な1次の再帰的な実装ではなくk回の積和演算(MAC)演算を実行する必要があるという事実は、ベクトル化の利点の一部を減少させます。非ベクトル化アプローチでは、出力ごとに2つのMACを使用するため、M個の出力を計算するには2 M回の演算が必要です。ベクトル化されたスキームは、M個の出力を一度に計算するため、M +プロセス中のMAC。したがって、操作の削減は Mの関数として次のように表すことができます。
。この効果は明らかにプラットフォームに大きく依存します。
方程式を4ステップに拡張し、行列乗算を使用するのはどうでしょうか。aは定数なので、1つの行列を事前に計算できます
複数の独立したストリームのフィルタリングを並列にベクトル化することが最も効率的です。
単一の長いストリームがある場合は、ストリームをいくつかの重複するセクションに分割し、独立したストリームであるかのようにこれらをフィルタリングすることもできます。
各ストリームの最初の数サンプルが正しくないため、オーバーラップが必要です。破棄する必要があるサンプルの量は、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サンプル。