3

16 個の uint8_t サイズの入力の絶対差の合計のネオン バージョンをコーディングしようとしています。

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;
}

私が書いたネオンコード:

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];
}

何らかの理由でバスエラーが発生します。私のテスト プログラムでは__attribute__ ((aligned (16)))、2 つの入力に gcc ディレクティブを使用しています。それらに割り当てられたメモリ アドレスから、入力が 16 バイトにアラインされていることがわかります。

問題の原因は何ですか?

4

1 に答える 1

2

r適切に配置されていることを確認する必要があります-変​​更:

int32_t r[4] = { 0, 0, 0, 0 };

に:

int32_t r[4] = { 0, 0, 0, 0 } __attribute__ ((aligned(16)));

ただし、このルーチンが有益である可能性は低いことに注意してください。これは、スカラー命令と NEON 命令の両方を大量に使用するためです。つまり、元のスカラー実装と同様のパフォーマンスが得られる可能性が高くなります。

于 2012-10-24T16:12:33.140 に答える