2013-04-05 5 views
1

Ниже приведено IIR code. Мне нужно векторизовать код, чтобы я мог эффективно писать код NEON.Код для векторизации для эффективной реализации

Пример векторизации Non Векторизованных код

for(i=0;i<100;i++) 
a[i] =a[i]*b[i];  //only one independent multiplication cannot take 
        //advantage of multiple multiplication units 

Векторизованный код

for(i=0;i<25;i++) 
{ 
a[i*4] =a[i*4]*b[i*4];    //four independent multiplications can use 
a[(i+1)*4] =a[(i+1)*4]*b[(i+1)*4]; // multiple multiplication units to perform the 
a[(i+2)*4] =a[(i+2)*4]*b[(i+2)*4]; //operation in parallel 
a[(i+3)*4] =a[(i+3)*4]*b[(i+3)*4]; 
} 

Пожалуйста, помогите мне в векторизации для цикла ниже, с тем, чтобы эффективно реализовать код, используя векторная способность аппаратного обеспечения (мое оборудование может одновременно выполнять 4 умножения).

main() 
    { 
     for(j=0;j<NUMBQUAD;j++) 
    { 
     for(i=2;i<SAMPLES+2 ;i++) 
     { 
      w[i] = x[i-2] + a1[j]* w[i-1] + a2[j]*w[i-2]; 
      y[i-2] = w[i] + b1[j]* w[i-1] + b2[j]*w[i-2]; 

     } 
     w[0]=0; 
     w[1] =0; 
    } 
    } 
+1

Сначала заставьте его работать. Я могу ошибаться, но, как правило, IIR получают доступ к более чем одному элементу в прямом цикле подачи. Доступ только к x [i-2]. –

+0

Что сказал @Aki - нет смысла пытаться оптимизировать сломанный код. Для фильтров IIR у вас есть проблемные зависимости - на самом деле проще реализовать 4 отдельных фильтра IIR параллельно с 4-сторонним SIMD, а не пытаться применить SIMD к одному фильтру IIR. –

+0

Это другая форма биквады IIR, и уравнения берутся по виду. Http://en.wikipedia.org/wiki/Digital_biquad_filter#Direct_Form_2 – Wolfrum

ответ

1

После того, как вы закрепили (или проверено) уравнения, следует заметить, что есть 4 независимых умножений в каждом раунде уравнения. Задача становится в поиске правильного и наименьшее количество инструкций переставлять входные векторы х [...], у [...], ш [...] в какой-то регистр

q0 = | w[i-1] | w[i-2] | w[i-1] | w[i-2]| 
    q1 = | a1[j] | a2[j] | b1[j] | b2[j] | // vld1.32 {d0,d1}, [r1]! 
    q2 = q0 .* q1 

Потенциально гораздо более эффективный метод смещения волнового фронта может быть достигнут путем инвертирования циклов for.

x0 = *x++; 

    w0 = x0 + a*w1 + b*w2; // pipeline warming stage 
    y0 = w0 + c*w1 + d*w2; // 

    [REPEAT THIS] 
    // W2 = W1; W1 = W0; 
    W0 = y0 + A*W1 + B*W2; 
    Y0 = W0 + C*W1 + D*W2; 
    // w2 = w1; w1 = w0; 

    x0 = *x++; 
    *output++= Y0; 

    w0 = x0 + a*w1 + b*w2; 
    y0 = w0 + c*w1 + d*w2; 
    [REPEAT ENDS] 

    W0 = y0 + A*W1 + B*W2; // pipeline cooling stage 
    Y0 = W0 + C*W1 + D*W2; 
    *output++= Y0; 

Хотя есть еще зависимости между х0> w0-> y0-> W0-> Y0, есть возможность полной 2-полосная параллелизм между строчными и прописными выражениями. Также можно попытаться избавиться от смещения значений w2=w1; w1=w0; путем разворачивания цикла и переименования вручную.

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

  • Нет связанных вопросов^_^