使用 neon 内在函数处理奇数元素

Handling elements that are odd number using neon intrinsics

我是 neon 内在函数的新手。我有两个包含 99 个元素的数组,我试图使用 neon 内在元素明智地添加它们。由于99不是8,16或32的倍数。可以处理96个元素如何处理剩下的3个元素。请帮忙 这是我写的代码

 #include <arm_neon.h>
 #define SIZE 99
 void addition(unsigned char A[],unsigned char B[],unsigned short int *addres)
{
   uint8x8_t v,v1;
   int i=0;
   for (i=0;i<SIZE;i=i+8){
   v = vld1_u8(&A[i]); // load the array from memory into a vector
   v1=vld1_u8(&B[I]);
   uint16x8_t t = vaddl_u8(v,v1);
   vst1q_u16(addres+i,t); // store the vector back to memory
  }
}

到目前为止,我想出的处理 SIMD 残差的最有效方法是我所说的“withold and rewind”方法。 (我想是我发明的)

void addl(uint16_t *pDst, uint8_t *pA, uint8_t *pB, intptr_t size)
{
    // assert(size >= 8);
    uint8x8_t a, b;
    uint16x8_t c;

    size -= 8; // withold

    do {
        do {
            size -= 8;
            a = vld1_u8(pA);
            b = vld1_u8(pB);
            c = vaddl_u8(a, b);
            vst1q_u16(pDst, c);
            pA += 8;
            pB += 8;
            pDst += 8;
        } while (size >= 0);

        pA += size;      // and rewind
        pB += size;
        pDst += size;
    } while (size > -8);
}

size 可以是任何大于等于 8 的数字。
但是存在三个缺点:

  • size 必须 >=8(大多数情况下没问题)
  • 您不能在 aarch32 程序集中使用对齐说明符(在内部函数中没有问题)
  • 在目标缓冲区还包含源数据(例如 alpha 混合 bitBLT)的情况下不可行(在这种情况下没问题)

PS:size 必须是 intptr_t 类型。否则该进程将在 64 位机器上崩溃。