2016-09-19 6 views
0

Im ARMおよびNEONプログラミングにはかなり新しいので、SAD(Sum of Absolute Difference)関数を最適化するタスクが与えられています。私はどこから始めるべきかわかりません、私は成功することなくNEONコードを生成するいくつかの方法を試しました。 シーケンシャル機能は次のようなものになります。ARM NEON 8x8 SADオペレーション

void sad_block_8x8(uint8_t *block1, uint8_t *block2, int stride, int *result) 
{ 
    int u, v; 

    *result = 0; 

    for (v = 0; v < 8; ++v) 
    { 
     for (u = 0; u < 8; ++u) 
     { 
      *result += abs(block2[v*stride+u] - block1[v*stride+u]); 
     } 
    } 
} 

をだから私の問題は、次のとおりです。

  1. 私は計算を行うと、変数resultに格納しない方法を反復ごと
  2. ためのレジスタをロードするにはどうすればよいです

ご協力いただきますようお願い申し上げます。

大丈夫...ので、私の最初の試みは、このようなものでした(動作しますが、私は極めて悪いネオンコードである知っているが)

void sad_block_8x8_2(uint8_t *block1, uint8_t *block2, int stride, int *result) 
{ 
int u, v; 
uint8x8_t m_1, m_2, m_o; 
uint8_t* test; 
test = (uint8_t*)malloc(v*u*sizeof(uint8_t));; 
*result = 0; 
for (v = 0; v < 8; ++v) 
{ 
    for(u = 0; u < 8; ++u) 
    { 
     m_1 = vld1_u8(&block1[v*stride]); 
     m_2 = vld1_u8(&block2[v*stride]); 

     m_o = vabd_u8(m_2, m_1); 
     vst1_u8(&test[v], m_o); 
     //printf("%d ", test[v]); 
     *result += (int)test[v]; 
    } 
} 
} 

任意のヘルプしてください?

+1

入力データブロックは 'const'でなければなりません。 NEON対応のコンパイラを試しましたが、これは自動的にベクトル化する可​​能性がありますか? – unwind

+0

8x8から8x1にするには、arm_neon.hで 'uint16x8_t vabal_u8(uint16x8_t、uint8x8_t、uint8x8_t)'を使用することができます – user3528438

答えて

0

これは、あなたが望んでいたSADアルゴリズムの少し良くし、より明確な実装は次のとおりです。

void neon_sad_block_8x8(uint8_t *__restrict block1, uint8_t * __restrict block2, int stride, int *__restrict result) 
{ 
     int i, j; 
     uint8x8_t neon_block1; 
     uint8x8_t neon_block2; 
     uint8x8_t res; 
     int sum = 0; 
     for (i = 0; i < 8; i++) {             
      neon_block1 = vld1_u8(&block1[i * stride]);      
      neon_block2 = vld1_u8(&block2[i * stride]);      
      res = vabd_u8(neon_block2, neon_block1);       
      sum += res[0] + res[1] + res[2] + res[3] + res[4] + res[5] + res[6] + res[7]; 
     } 
     *result = sum; 
} 

このコードがあります

  • つだけループ
  • ループ
  • にはbreak文はありません
  • ポインタは__restrictによって保護されています
+0

uint8x8x4_tのようなベクトルデータ型を使用することも考えられます。uint8x8_t型の単純な配列として定義されています: typedef struct int8x8x4_t { int8x8_t val [4]; } int8x8x4_t; – nachiketkulk

+0

64ビットアーキテクチャでコードを実行している場合、uint8_t vaddvq_u8()関数を使用して1つの命令のレーンにあるすべての要素を追加することもできます。 – nachiketkulk

関連する問題