将q-register中的128位数据(和)转换为16位数据的高效算法

时间:2012-08-04 10:33:21

标签: embedded arm neon intrinsics cortex-a8

我在q-register中有128位数据。我想总结这个q寄存器中的16位数据块,最后得到一个16位的最终和(超过16位的任何进位都应该被加到这个16位数的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);

}

它仍然不完整,有点笨拙..任何帮助将不胜感激。

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

我的目标是将16位块(模16位)相加,以下片段可以做到:

uin16_t convert128to16(uint16x8_t data128){

  data128 += (data128 >> 64);

  data128 += (data128 >> 32);

  data128 += (data128 >> 16);

  return data128 & 0xffff;

}