2012-02-26 6 views
1

NEONコンパイラ組み込み関数を頭に入れようとしていて、例題から始めていくつかの質問をすることができました。ARMネオンコンパイラ組み込み関数を使用した深度変換

この実験では、32ビットRGBを16ビットBGRに変換したいと考えています。 NEONコンパイラ組み込み関数を使用するために次のコードを変換するのに適した方法は何ですか?私がここで抱えている問題は、16ビットが私が見ることができる固有のものと一致しないことです。 16x4の16x8などがありますが、私はこのアプローチにどのように対処する必要があるかについて私の思考を包み込む運がほとんどありません。任意のヒント?

ここに、私が変換しようとしているコードがあります。

typedef struct { 
    uint16_t b:5, g:6, r:5; 
} _color16; 

static int depth_transform_32_to_16_c (VisVideo *dest, VisVideo *src) 
{ 
    int x, y; 
    int w; 
    int h; 

    _color16 *dbuf = visual_video_get_pixels (dest); 
    uint8_t *sbuf = visual_video_get_pixels (src); 

    uint16x8 

    int ddiff; 
    int sdiff; 

    depth_transform_get_smallest (dest, src, &w, &h); 

    ddiff = (dest->pitch/dest->bpp) - w; 
    sdiff = src->pitch - (w * src->bpp); 

    for (y = 0; y < h; y++) { 
     for (x = 0; x < w; x++) { 
      dbuf->b = *(sbuf++) >> 3; 
      dbuf->g = *(sbuf++) >> 2; 
      dbuf->r = *(sbuf++) >> 3; 

      dbuf++; 
      sbuf++; 
     } 

     dbuf += ddiff; 
     sbuf += sdiff; 
    } 

    return VISUAL_OK; 
} 

編集:ああ、何らかの理由で、私はこれを考慮16x3ビットを見ていたが、私たちは5,6,5 = 16ビットを見ています。私はシフトが必要であることを知っている。うーん。

答えて

4

NEONは128ビット幅のレジスタを使用しているため、概念的には32ビットRGBの4ピクセルで読み込み、それらのビット単位の操作を使用して最終的に16ビットピクセルを書き出します。最良のパフォーマンスを得るには、2つの128ビット入力(8つの32ビットピクセル)を組み合わせて1つの128の出力を生成することが1つの所見です。これにより、メモリアクセスがより効率的になります。

これについてもう一つ考えてみるには、内部ループのコンテンツを取得していて、並列に4つのピクセルを処理しているということです。元のコードで作業するのが少し難しいのは、ビットフィールドを使用しているため、「魔法」の一部が隠されていることです。あなたのCコードを32ビットから16ビットへと書き直し、シフトを使用すると、そのコードはより自然にSIMDに変換され、そのコンテキスト内で複数のデータを扱う方法を視覚化することができます。

あなただけの各32ビットコンポーネントを見れば - > 16ビット変換は:

00000000RRRRRRRRGGGGGGGGBBBBBBBB 
0000000000000000BBBBBGGGGGGRRRRR 

これは、あなたが4つの画素に対して並列に行うために必要なものを視覚化することができます。シフト、抽出、結合。いくつかのビット操作では、レジスタの幅は関係ありません(たとえば、4つの32ビットレジスタまたは8つの16ビットレジスタが同じである)が、これを4 32ビットレーンと考えることができます。

ラフ擬似コード:

  • 読む(ベクター負荷)128ビットレジスタ= 4 32ビットピクセル。
  • シフト緑(すべての4つのコンポーネント)が右ビット位置になります。
  • 別のレジスタにグリーンをマスクアウトします(およびマスクを使用)。 (概念的には4×32ビットの「モード」にある)
  • シフト赤(すべての4つの成分)が右ビット位置にある。
  • もう1つのレジスタに赤をマスクアウトします。
  • シフト青が右のビット位置にシフトします。
  • ブルーを別のレジスタにマスクアウトします。
  • シフト赤と青から右のビット位置。
  • ビット単位でまたはを組み合わせて使用​​します。
  • これで、4つの16ビット値と32ビットのアラインメントが得られます。 (これまでは概念的には4×32ビットのままでした)
  • もう1組の4ピクセルで繰り返します。
  • これらの2つのセットをNEON unzip(VUZP)と組み合わせて、1つの128ビット/ 8ピクセルレジスタを生成します。
  • これらのピクセルを書き込む(ベクトルストア)。
関連する問題