I’m trying to code a neon version of Sum of Absolute Difference of a 16 uint8_t sized inputs:
inline static int f_sad_16(const uint8_t* a, const uint8_t* b)
{
int sad = 0;
for (int i = 0; i < 16; i++) {
sad += abs(static_cast<int>(a[i]) - static_cast<int>(b[i]));
}
return sad;
}
The neon code I wrote:
inline static int f_sad_16_neon(const uint8_t* a, const uint8_t* b)
{
int32_t r[4] = { 0, 0, 0, 0 };
uint8x16_t va, vb, vr;
va = vld1q_u8(a);
vb = vld1q_u8(b);
vr = vabdq_u8(va, vb);
uint16x8_t vr1 = vpaddlq_u8 (vr );
uint32x4_t vr2 = vpaddlq_u16(vr1);
uint64x2_t vr3 = vpaddlq_u32(vr2);
vst1q_u64 (reinterpret_cast<uint64_t*>(r), vr3);
return r[0] + r[2];
}
For some reason I get a bus error. My test program uses the __attribute__ ((aligned (16))) gcc directive for the two inputs, and I can see by the memory addresses assigned to them that the inputs are 16-byte aligned.
What can be the source of the problem?
You need to make sure that
ris properly aligned – change:to:
Note however that it’s unlikely that this routine will be beneficial, as it uses a significant number of both scalar and NEON instructions, which means it will most likely have performance similar to that of your original scalar implementation.