Преобразование коротких в int и суммирование с NEON - PullRequest
0 голосов
/ 26 января 2012

Я хочу преобразовать следующую функцию в NEON:

int  dot4_c(unsigned char v0[4], unsigned char v1[4]){
      int r=0;
      r = v0[0]*v1[0];
      r += v0[1]*v1[1];
      r += v0[2]*v1[2];  
      r += v0[3]*v1[3];
return r;
}

Я думаю, что почти делаю это, но есть ошибка, потому что она не работает хорошо

int dot4_neon_hfp(unsigned char v0[4], unsigned char v1[4])
{

asm volatile (
              "vld1.16      {d2, d3}, [%0]          \n\t"   //d2={x0,y0}, d3={z0, w0}
              "vld1.16      {d4, d5}, [%1]          \n\t"   //d4={x1,y1}, d5={z1, w1}
              "vcvt.32.u16      d2, d2                  \n\t" //conversion
              "vcvt.32.u16      d3, d3                  \n\t"
              "vcvt.32.u16      d4, d4                  \n\t"
              "vcvt.32.u16      d5, d5                  \n\t"

              "vmul.32      d0, d2, d4              \n\t"   //d0= d2*d4
              "vmla.32      d0, d3, d5              \n\t"   //d0 = d0 + d3*d5 
              "vpadd.32         d0, d0              \n\t"   //d0 = d[0] + d[1]
              :: "r"(v0), "r"(v1) : 
              );    

}

Как мне заставить это работать?

1 Ответ

2 голосов
/ 27 января 2012

Как уже упоминалось, вы должны загружать не менее 8 байтов одновременно с NEON.Пока загрузка не проходит за пределы буфера, вы можете игнорировать лишние байты.Вот как это сделать с помощью встроенных функций:

uint8x8_t v0_vec, v1_vec;
uint16x8_t vproduct;
uint32x2_t vsum32;

v0_vec = vld1_u8(v0); // extra bytes will be ignored as long as you can safely read them
v1_vec = vld1_u8(v1);
// you didn't specify if the product of your vector fits in 8-bits, so I assume it needs to be widened to 16-bits
vproduct = vmull_u8(v0_vec, v1_vec);
vsum32 = vpaddl_u16(vget_low_u16(vproduct)); // pairwise add lower half (first 4 u16's)
return vsum32.val[0] + vsum32.val[1];

Если вы абсолютно не можете загрузить 8 байтов из указателей источника, вы можете вручную загрузить 32-битное значение в регистр NEON (4 байта)а затем приведите его к соответствующему внутреннему типу.

...