Предполагая, что вы выполняете векторные операции 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]
Я знаю, что вышеизложенное трудно читать (возможно,мы можем перенести этот вопрос на Обработка сигналов , и я могу повторно набрать его в LaTeX).Но, учитывая начальное условие y[n]
(которое предполагается последним выходом, вычисленным на предыдущей векторизованной итерации), вы можете рассчитать следующие выходные данные M
параллельно, так как остальная часть развернутого фильтра имеет FIR-подобныйструктура.
У этого подхода есть несколько предостережений: если M
становится большим, то вы умножаете кучу чисел, чтобы получить эффективные коэффициенты FIR для развернутых фильтров.В зависимости от вашего числового формата и значения a
, это может иметь значение для числовой точности.Кроме того, при таком подходе вы не получите ускорение в 10 * 10 раз: в итоге вы рассчитываете y[n+k]
с учетом того, что равняется КИХ-фильтру k
.Несмотря на то, что вы вычисляете M
выходных данных параллельно, тот факт, что вместо простой рекурсивной реализации первого порядка вам нужно делать k
операций умножения, уменьшает некоторые преимущества векторизации.