6

レーンにすべての要素を追加できる組み込み関数はありますか? Neon を使用して 8 つの数値を乗算していますが、結果を合計する必要があります。これは、私が現在行っていることを示すために言い換えられたコードです (これはおそらく最適化されている可能性があります)。

int16_t p[8], q[8], r[8];
int32_t sum;
int16x8_t pneon, qneon, result;

p[0] = some_number;
p[1] = some_other_number; 
//etc etc
pneon = vld1q_s16(p);

q[0] = some_other_other_number;
q[1] = some_other_other_other_number;
//etc etc
qneon = vld1q_s16(q);
result = vmulq_s16(p,q);
vst1q_s16(r,result);
sum = ((int32_t) r[0] + (int32_t) r[1] + ... //etc );

これを行う「より良い」方法はありますか?

4

3 に答える 3

5

新しいアーム 64 ビット アーキテクチャをターゲットにしている場合は、ADDV が適切な命令です。

コードは次のようになります。

qneon = vld1q_s16(q);
result = vmulq_s16(p,q);
sum = vaddvq_s16(result);

それでおしまい。ベクトル レジスタ内のすべてのレーンを合計する命令は 1 つだけです。

残念ながら、この命令は、古い 32 ビット アーム アーキテクチャでは機能しません。

于 2015-07-10T05:05:42.780 に答える
0

このようなものはかなり最適に機能するはずです(注意:テストされていません)

const int16x4_t result_low = vget_low_s16(result); // Extract low 4 elements
const int16x4_t result_high = vget_high_s16(result); // Extract high 4 elements
const int32x4_t twopartsum = vaddl_s16(result_low, result_high); // Extend to 32 bits and add (4 partial 32-bit sums are formed)
const int32x2_t twopartsum_low = vget_low_s32(twopartsum); // Extract 2 low 32-bit partial sums
const int32x2_t twopartsum_high = vget_high_s32(twopartsum); // Extract 2 high 32-bit partial sums
const int32x2_t fourpartsum = vadd_s32(twopartsum_low, twopartsum_high); // Add partial sums (2 partial 32-bit sum are formed)
const int32x2_t eightpartsum = vpadd_s32(fourpartsum, fourpartsum); // Final reduction
const int32_t sum = vget_lane_s32(eightpartsum, 0); // Move to general-purpose registers
于 2012-08-29T05:27:48.293 に答える