2

q-register に 128 ビットのデータがあります。この q レジスタ内の個々の 16 ビット ブロックを合計して、最終的に 16 ビットの最終的な合計を取得したいと考えています (16 ビットを超えるキャリーは取得して、この 16 ビット num の LSB に追加する必要があります)。

私が達成したいのは:

VADD.U16 (一部の 16 ビット変数) {q0[0] q0[1] q0[2] .... q0[7]}

しかし、組み込み関数を使用すると、

誰かが私にこれのアルゴリズムを教えていただければ幸いです。

ペアワイズ加算を使用してみましたが、かなり不器用な解決策になってしまいました..

見た目は次のとおりです。

int convert128to16(uint16x8_t data128){

    uint16_t data16 = 0;
    uint16x4_t ddata;
    print16(data128);

    uint32x4_t data = vpaddlq_u16(data128);
    print32(data);

    uint16x4_t data_hi = vget_high_u16(data);
    print16x4(data_hi);

    uint16x4_t data_low = vget_low_u16(data);
    print16x4(data_low);

    ddata = vpadd_u16( data_hi, data_low);
    print16x4(ddata);

}

それはまだ不完全で、少し不器用です..どんな助けでも大歓迎です。

4

2 に答える 2

3

水平加算命令を使用できます。

ここにフラグメントがあります:

  uint16x8_t input = /* load your data128 here */

  uint64x2_t temp   = vpaddlq_u32 (vpaddlq_u16 (input)); 

  uint64x1_t result = vadd_u64 (vget_high_u64 (temp), 
                                vget_low_u64  (temp));


  // result now contains the sum of all 16 bit unsigned words
  // stored in data128. 

  // to add the values that overflow from 16 bit just do another 16 bit
  // horizontal addition and return the lowest 16 bit as the final result:

 uint16x4_t w = vpadd_u16 (
     vreinterpret_u16_u64 (result),                              
     vreinterpret_u16_u64 (result));

 uint16_t wrappedResult = vget_lane_u16 (w, 0);
于 2012-08-04T12:31:40.213 に答える
1

あなたの目標が 16 ビット チャンク (モジュロ 16 ビット) を合計することである場合、次のフラグメントが実行されます。

uin16_t convert128to16(uint16x8_t data128){

  data128 += (data128 >> 64);

  data128 += (data128 >> 32);

  data128 += (data128 >> 16);

  return data128 & 0xffff;

}
于 2012-08-04T12:21:33.820 に答える