2012-01-05 2 views
2

У меня есть простой однополюсный фильтр низких частот (для параметра сглаживания), что можно объяснить по следующей формуле:ARM NEON простой фильтр низких частот векторизации

y[n] = (1-a) * y[n-1] + a * x[n] 

Как эффективный векторизовать этот случай на ARM Neon - используя встроенные функции? Является ли это возможным? Проблема в том, что для каждого вычисления требуется предыдущий результат.

+0

В моем ответе ниже рассказывается о том, как реструктурировать проблему для параллельного вычисления, но для более конкретного ответа, содержащего специфику реализации NEON, нужно знать, какой формат номера вы используете, и т. Д. –

ответ

0

Вы можете только на самом деле векторизовать это, если у вас есть более одного сигнала, к которому вы хотите применить тот же фильтр, например. если это стерео аудиосигнал, вы можете параллельно обрабатывать левый и правый каналы. Очевидно, что четыре или восемь каналов будут еще лучше.

0

В общем, вы можете только векторизовать полностью независимые множества вычислений. Но в вашем нижнем проходе IIR каждый выход зависит от другого (кроме 1-го), поэтому векторизация невозможна.

Если ваша переменная «a» достаточно велика, чтобы (1-a)^n быстро распалась ниже нужного уровня шума или допустила ошибку, вы могли бы заменить короткое приближение КИХ-фильтра для вашего IIR и вместо этого векторизовать эту свертку , Но это вряд ли будет быстрее.

0

Как насчет расширения уравнений на 4 шага и использования матричного умножения? a постоянна, поэтому одна матрица может быть предварительно рассчитана

2

Предполагая, что вы выполняете векторные операции 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 параллельно, тот факт, что вы должны делать операции умножения-аккумулирования, а не простой рекурсивной реализации первого порядка, уменьшает некоторые преимущества для векторизации.

+0

Is векторизованная версия с 9 операциями более эффективна, чем использование скалярной версии orignal, которая имеет всего три операции?Хорошо, но в целом скалярный будет иметь 4 * 3 = 12 операций, поэтому, вероятно, немного медленнее, чем вектор, верно? –

+1

Да, это то, что я получал в своем последнем абзаце; нет такой большой пользы, как вам хотелось бы с точки зрения количества операций, только до 50% вместо '1/M'. [Очень похожая версия этого вопроса перекрестно размещена в обработке сигналов] (http://dsp.stackexchange.com/questions/1075/how-can-i-vectorize-the-computations-for-a-first-order -рекурсивный фильтр), уделяя больше внимания структуре проблем и количеству операций, чем что-либо NEON-specific. Там есть некоторые дополнительные сведения. –

Смежные вопросы