2013-05-31 3 views
0

Я пытаюсь выяснить, может ли и какой конкретный существующий код быть распараллелен для использования в блоке ARON Cortex-A9 NEON SIMD. Это код:Возможно ли распараллелить фильтр для ARM NEON?

for(int i=0; i < 11; i++) 
{ 
    f4UF1 *= F[i]; 

    A[i][2] = A[i][1]; 
    A[i][1] = A[i][0]; 
    A[i][0] = f4UF1; 

    B[i][2] = B[i][1]; 
    B[i][1] = B[i][0]; 

    C[i] = 0; 

    C[i] += D[i][0] * A[i][0]; 
    C[i] += D[i][1] * A[i][1]; 
    C[i] += D[i][2] * A[i][2]; 

    C[i] -= E[i][1] * B[i][1]; 
    C[i] -= E[i][2] * B[i][2]; 

    B[i][0] = C[i]/E[i][0]; 

    f4UF1 = B[i][0]; 
} 

Я посмотрел на код для совсем немного, и я почти уверен, что она не может быть распараллеливание эффективно, но я думал, я мог бы дать ему попробовать задать здесь. Я не ожидаю готового кода, просто идеи о том, как это сделать. Спасибо :)

+0

какие типы данных? вы должны вставить что-то, что может удовлетворить компилятор. – auselen

+0

Компиляция и рассмотрение результатов могут дать некоторое представление. – marko

+0

Вы можете сдвигать элементы с помощью инструкции vext. Вы также можете умножить/добавить. Похоже, вы можете улучшить ситуацию на несколько циклов, если вы напишете ее в NEON. Единственная проблема - это разрыв, который нужно будет размножить. – BitBank

ответ

1

Так что да, это похоже на биквад, для которого коэффициенты изменены для каждого образца, возможно потому, что вы их сглаживаете.

Как отметил комментатор, вы, вероятно, захотите предварительно вычислить масштабный коэффициент 1/E[i][0] и, возможно, переверните его в другие коэффициенты, чтобы уменьшить количество умножений, особенно на платформах с плавающей запятой. Вы также можете часто нормализовать биквад, чтобы избавиться от D[i][0] (сделав его 1.0) и просто примените скаляр для всего вывода.

И, конечно же, вы, наверное, уже поняли, что вы хотите, чтобы держать все в регистрах во время цикла, а затем только записывать их в память после того, как цикл закончен ... ;-)

После этого там это два метода векторизации, о которых я знаю (хотя меня также интересуют идеи Нилса):

  1. Прокрутка канала - самый простой. Если вам необходимо применить фильтры к нескольким наборам данных одновременно (очень часто для стереофонического звука, например), вы можете одновременно использовать два набора коэффициентов с двумя наборами аудиоданных. Я обнаружил, что Neon предоставляет только правильное количество регистров для двух каналов, если вы используете всю плавучую точку SP. Мгновенное 2x ускорение действительно.
  2. Loop разворачивания. Это немного сложно описать здесь, но, к счастью, здесь есть хорошая страница: http://reanimator-web.appspot.com/articles/simdiir. Этот метод добавляет пары полюсов/нулей, чтобы по существу вычислить больше образцов одновременно. Тем не менее, дополнительные полюса, конечно, добавляют дополнительные условия стабильности фильтра, поэтому вам нужно быть осторожными. В вашем случае, когда коэффициенты кажутся динамическими, это, вероятно, какой-то кошмар для обеспечения.
Смежные вопросы