1У меня есть 3-х ступенчатый биквад-фильтр для фильтрации данных входного сигнала (входной). Во время оптимизации я развернул всю l oop и использовал встроенную нагрузку (vld1_s32), умноженную на накопление (vmlal_s32), полагая, что эта оптимизация сократит время, затрачиваемое процессором на код. Но я не получил лучшие результаты. Можно ли каким-либо другим способом оптимизировать следующий код с помощью ARM NEON Intrinsics (архитектура SIMD)?
Примечание. Значения буфера (x) и коэффициентов (h) являются 32-разрядными целыми числами.
long long int sum;
for(i1=0;i1<100;i1++)
{
temp = input[i1];//32 bit (int) datatype
for(i=0;i<3;i++)
{
sum = x[1+2*i] * h[1+5*i];
sum += x[3+2*i] * h[3+5*i];
sum = sum<<1; //center tapping
sum += x[2+2*i] * h[2+5*i];
sum += x[4+2*i] * h[4+5*i];
sum += temp * h[0+5*i];
x[2+2*i] = x[1+2*i];
x[1+2*i] = temp;
temp = sum>>31;
}
printf("%lld\n",temp);
}
Оптимизированный код: (я считаю, что это только частичная оптимизация)
int32x2_t x_vec,h_vec;
int64x2_t result_vec;
for(i1=0;i1<100;i1++)
{
temp =input[i1];
for (i = 0; i < 3; i++)
{
result_vec = vdupq_n_s64(0);
for (j = 0; j < 2; j++) // 5 coefficients in total for a biquad - 4 used here
{
x_vec = vld1_s32(&x[1 + 2 * i + 2 * j]);
h_vec = vld1_s32(&h[1 + 5 * i + 2 * j]);
result_vec = vmlal_s32(result_vec, x_vec, h_vec);
}
sum = vadd_s64(result_vec[0], result_vec[1]);
sum = sum + temp * h[0 + 5 * i]) //- remaining one used here
sum += x[1 + 2 * i] * h[1 + 5 * i]);//adding one more time
sum += x[3 + 2 * i] * h[3 + 5 * i];//adding one more time
x[2 + 2 * i] = x[1 + 2 * i];
x[1 + 2 * i] = temp;
temp = sum>>31;
}
printf("%d\n",temp);
}