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