Wie kann ich die Berechnungen für einen rekursiven Filter erster Ordnung vektorisieren?

9

Ich habe ein einfaches einpoliges Tiefpassfilter (zur Parameterglättung), das durch die folgende Formel erklärt werden kann:

y[n]=(1a)y[n1]+ax[n]

Die von mir verwendete Architektur hat Zugriff auf SIMD-Befehle (Single-Instruction, Multiple-Data), mit denen mehrere vektorisierte Berechnungen parallel ausgeführt werden können. Ich möchte diese Funktion nutzen, bin mir aber nicht sicher, wie ich das für einen rekursiven Filter wie diesen machen soll. Das Problem ist, dass jede Berechnung ein vorheriges Ergebnis benötigt.

user1132968
quelle
Könnte jemand bitte klarstellen, warum dies als "Off Topic" geschlossen wurde?
Paul R
Die Frage überschneidet sich zwischen hier und Stapelüberlauf. In der ursprünglichen Frage wurde speziell gefragt, wie die Implementierung mit ARM NEON-Erweiterungen erfolgen soll. Die Frage wird auf beiden Seiten leben; Es wurde hier bearbeitet, um es eher zu einer theoretischen Diskussion über die Strukturierung des Problems zu machen, um die Parallelität auszunutzen.
Jason R
@PaulR Ich habe gestern darum gebeten, dass es hierher migriert wird, aber Phonon war der festen Überzeugung, dass es zu SO gehört und nicht hier. Ich gebe zu, ich weiß nichts über ARM NEON und er hat wahrscheinlich Recht und ich respektiere sein Urteil. Siehe diese Meta-Frage . Meine gelöschte Antwort sagte im Grunde, dass ich mit Jason R einverstanden bin und dass Benutzer solche Fragen für die Migration
markieren
1
Vielen Dank für die Klarstellung. Ich habe mein Bestes gegeben, um DSP-bezogene Fragen hierher zu migrieren, um unser Profil zu verbessern. Daher war ich besorgt, ob dies das Richtige war, als diese Frage geschlossen wurde. Ich bin froh zu sehen, dass es jetzt in einer allgemeineren Form wieder geöffnet ist.
Paul R

Antworten:

7

Unter der Annahme, dass Sie Vektoroperationen Elemente gleichzeitig ausführen , können Sie die Differenzgleichung für den einfachen einpoligen Filter ziemlich einfach um den Faktor M abrollen. Angenommen, Sie haben bereits alle Ausgaben bis zu y [ n ] berechnet . Dann können Sie die folgenden wie folgt berechnen: y [ n + 1 ]MMy[n]

y[n+1]=(1a)y[n]+ax[n+1]y[n+2]=(1a)y[n+1]+ax[n+2]=(1a)((1a)y[n]+ax[n+1])+ax[n+2]=(1a)2y[n]+a(1a)x[n+1]+ax[n+2]

Im Allgemeinen können Sie schreiben als:y[n+k]

y[n+k]=(1a)ky[n]+i=1ka(1a)kix[n+i]

Für jeden Abtastindex sieht dies wie ein FIR-Filter mit k + 1 Abgriffen aus: Ein Abgriff multipliziert den letzten Filterausgang y [ n ] und die anderen k Abgriffe multiplizieren die Filtereingänge x [ n + 1 ] , , x [ n + k ] . Das Schöne ist, dass die für alle diese Abgriffe verwendeten Koeffizienten vorberechnet werden können, sodass Sie den rekursiven Filter in M M + 1 abrollen könnenn+kk+1y[n]kx[n+1],,x[n+k]M M+1-tippen Sie auf parallele nicht rekursive Filter (diese Filter berechnen die Ausgangsabtastwerte ) und aktualisieren den Rückkopplungsterm alle M Ausgangsabtastwerte. Wenn also eine Anfangsbedingung y [ n ] gegeben ist (die als die letzte Ausgabe angenommen wird, die bei der vorherigen vektorisierten Iteration berechnet wurde), können Sie die nächsten M Ausgaben parallel berechnen .y[n+1],,y[n+M]My[n]M

Dieser Ansatz weist einige Einschränkungen auf:

  • Ma

  • My[n+k]kMk2MMMM+1M

    R=M+12M=12(1+1M)

    MM=4M=8y[n]y[n1]. Dieser Effekt ist offensichtlich sehr plattformabhängig.

Jason R.
quelle
3

Im Allgemeinen können Sie nur völlig unabhängige Berechnungssätze vektorisieren. In Ihrem IIR-Tiefpass ist jedoch jede Ausgabe von einer anderen abhängig (mit Ausnahme der ersten), sodass eine Vektorisierung nicht möglich ist.

Wenn Ihre Variable "a" groß genug ist, dass (1-a) ^ n schnell unter das gewünschte Grundrauschen oder den zulässigen Fehler abfällt, können Sie Ihre IIR durch eine kurze FIR-Filter-Näherung ersetzen und stattdessen diese Faltung vektorisieren. Aber das wird wahrscheinlich nicht schneller sein.

hotpaw2
quelle
2

Sie können dies nur dann wirklich effektiv vektorisieren, wenn Sie mehr als ein Signal haben, auf das Sie denselben Filter anwenden möchten. Wenn es sich beispielsweise um ein Stereo-Audiosignal handelt, können Sie den linken und rechten Kanal parallel verarbeiten. Vier oder acht Kanäle parallel wären natürlich noch besser.

Paul R.
quelle
0

Wie wäre es, wenn Sie Gleichungen auf 4 Schritte erweitern und die Matrixmultiplikation verwenden? a ist konstant, so dass eine Matrix vorberechnet werden kann


quelle
0

Am effizientesten ist es, die Filterung mehrerer unabhängiger Streams parallel zu vektorisieren.

Wenn Sie nur einen einzigen langen Stream haben, können Sie den Stream auch in mehrere überlappende Abschnitte aufteilen und diese filtern, als wären sie unabhängige Streams.

Sie möchten eine Überlappung, da die ersten Stichproben jedes Streams falsch sind. Die Anzahl der zu verwerfenden Proben hängt vom Wert von a und der gewünschten Genauigkeit ab. Sie sollten ungefähr n Proben verwerfen, bei denen (1 / a) (1-a) ** n <eps ist, damit das Ergebnis auf eps * max (| x [i] |) genau ist.

Wenn beispielsweise a = 0,1 ist, ist der durch (1 / a) (1-a) ^ n verursachte Fehler in 128 Abtastwerten kleiner als das LSB in einer 16-Bit-Ganzzahl, während Sie für a = 0,9 nur verwerfen müssten etwa 6 Proben.

Peter de Rivaz
quelle