Я пытаюсь написать оптимизированный точечный продукт для процессора ARM A8, используя встроенные функции Neon, но у меня возникли небольшие проблемы. Прежде всего, есть ли какая-нибудь библиотека, которая уже это реализует? Мой код, кажется, работает, но вызывает некоторые тихие сбои во время выполнения - я думаю, это связано с небольшой потерей точности по сравнению с неоптимизированным кодом. Есть ли лучший способ выполнить то, что я пытаюсь сделать? Буду очень признателен за любую помощь или предложения. Заранее спасибо.
Этот конкретный скалярный продукт представляет собой 32-битный комплекс с плавающей запятой * 32-битный комплекс с плавающей запятой.
Вот неоптимизированный код:
double sum_re = 0.0;
double sum_im = 0.0;
for(int i=0; i<len; i++, src1++, src2++)
{
sum_re += *src1 * src2->re;
sum_im += *src1 * src2->im;
}
Вот моя оптимизированная версия:
float sum_re = 0.0;
float sum_im = 0.0;
float to_sum_re[4] = {0,0,0,0};
float to_sum_im[4] = {0,0,0,0};
float32x4_t tmp_sum_re, tmp_sum_im, source1;
float32x4x2_t source2;
tmp_sum_re = vld1q_f32(to_sum_re);
tmp_sum_im = vld1q_f32(to_sum_im);
int i = 0;
while (i < (len & ~3)) {
source1 = vld1q_f32(&src1[i]);
source2 = vld2q_f32((const float32_t*)&src2[i]);
tmp_sum_re = vmlaq_f32(tmp_sum_re, source1, source2.val[0]);
tmp_sum_im = vmlaq_f32(tmp_sum_im, source1, source2.val[1]);
i += 4;
}
if (len & ~3) {
vst1q_f32(to_sum_re, tmp_sum_re);
vst1q_f32(to_sum_im, tmp_sum_im);
sum_re += to_sum_re[0] + to_sum_re[1] + to_sum_re[2] + to_sum_re[3];
sum_im += to_sum_im[0] + to_sum_im[1] + to_sum_im[2] + to_sum_im[3];
}
while (i < len)
{
sum_re += src1[i] * src2[i].re;
sum_im += src1[i] * src2[i].im;
i++;
}