2017-07-20 26 views
0

8ビット固定小数点演算を行っていますが、配列とB配列の両方がQ7形式であり、それらの和の積を求めます。 デモコード:アームネオン8ビット乗算加算和を32ビットベクトルに使用する方法

int8_t ra1[], ra2[], rb[]; 
int8x16_t va1, va2, vb; 
int16x4_t vsum1, vsum2; 
va1 = vld1q_s8(ra1); 
va2 = vld1q_s8(ra2); 
vb = vld1q_s8(rb); 
vsum1 = vdup_n_s16(0); 
vsum2 = vdup_n_s16(0); 
    for (......) 
    vsum1 = vmlal_s8(vsum1, vget_high_s8(va1), vget_high_s8(vb)); 
    vsum1 = vmlal_s8(vsum1, vget_low_s8(va1), vget_low_s8(vb)); 

合計+ = a * b;この合計は16ビット、それは簡単にオーバーフローすることができますので、* Q7×Q7 16ビットはQ15を表すことができます。また、私は右にQ7xQ7の結果をシフトすることはできません、私は高精度を維持する必要があります。 どのように私はネオンを使用することができます、私は合計が32ビットa、bはまだ8ビットです。私は転送する必要はありません16ビットとvmlal_s16を使用して、それはゆっくりとなります。 1つの指示時間で。 ネオンの組み込み関数にはこの関数がありません。おそらくネオンのアセンブリコードでこれを行うことができます。誰が助けることができますか?ありがとう。 Hereは、vmlaアセンブリコードの情報です。たぶん私はそれを使用することができます。いくつかのアドバイスを与えてください、私はアセンブリコードに慣れていません。

+0

乗算が遅くなる前に 'a'と' b'を16bitに変換することは確実ですか? AFAIRでは、少なくとも一部のNEON実装では、ハードウェアに16ビットの乗数を持つため、「8ビット×8ビット」のベクトル乗算を「16ビット×16ビット」のベクトル乗算として2倍の時間を要します。この場合は、乗算が有効に追加される前に拡大することを意味します。 – EOF

答えて

0

私はこのコード例は、役立ちます願っています:

inline int32x4_t Correlation(const int8x16_t & a, const int8x16_t & b) 
{ 
    int16x8_t lo = vmull_s8(vget_low_s8(a), vget_low_s8(b)); 
    int16x8_t hi = vmull_s8(vget_high_s8(a), vget_high_s8(b)); 
    return vaddq_s32(vpaddlq_s16(lo), vpaddlq_s16(hi)); 
} 

void CorrelationSum(const int8_t * a, const int8_t * b, size_t bStride, size_t size, int32_t * sum) 
{ 
    int32x4_t sums = vdupq_n_s32(0); 
    for (size_t i = 0; i < size; i += 16) 
     sums = vaddq_s32(sums, Correlation(vld1q_s8(a + i), vld1q_s8(b + i))); 
    *sum = vgetq_lane_s32(sums, 0) + vgetq_lane_s32(sums, 1) + vgetq_lane_s32(sums, 2) + vgetq_lane_s32(sums, 3); 
} 

注:この例では、関数Simd::Neon::CorrelationSum()に基づいています。また、私は)(代わりにvld1q_s8の)(次の関数のロードを使用することをお勧めします:

inline int8x16_t Load(const int8_t * p) 
{ 
#ifdef __GNUC__ 
    __builtin_prefetch(p + 384); 
#endif 
    return vld1q_s8(p); 
} 

プリフェッチを使用して、パフォーマンスへの15から20パーセントを追加します。

+0

ありがとう、しかし、あなたは4つの命令、私は1つの命令を使用して、私はこの機能が必要十分速いです。私は16ビットで固定piontをやった、私はvmlalのような命令が必要なので、私の8bit固定小数点データが大きすぎるので、私は32bitでそれを合計する必要があります。 – guxiangtao

+0

このタスクはメモリスループットによって制限されるため、問題はありません。 – ErmIg

+0

ありがとう、私はそれを試してみます。 – guxiangtao

関連する問題