巨大な配列を xor しようとして、uint32
NEON コプロセッサを使用することにしました。
c
私は2つのバージョンを実装しました:
バージョン 1:
uint32_t xor_array_ver_1(uint32_t *array, int size)
{
uint32x2_t acc = vmov_n_u32(0);
uint32_t acc1 = 0;
for (; size != 0; size -= 2) {
uint32x2_t vec;
vec = vld1_u32(array);
array += 2;
acc = veor_u32(acc, vec);
}
acc1 = vget_lane_u32(acc,0) ^ vget_lane_u32(acc,1);
return acc1;
}
バージョン 2:
uint32_t xor_array_ver_2(uint32_t *array, int size)
{
uint32x4_t acc = vmovq_n_u32(0);
uint32_t acc1 = 0;
for (; size != 0; size -= 4) {
uint32x4_t vec;
vec = vld1q_u32(array);
array += 4;
acc = veorq_u32(acc, vec);
}
acc1 ^= vgetq_lane_u32(acc,0);
acc1 ^= vgetq_lane_u32(acc,1);
acc1 ^= vgetq_lane_u32(acc,2);
acc1 ^= vgetq_lane_u32(acc,3);
return acc1;
}
上記の 2 つのバージョンを従来の xor 実装と比較すると、次のようになります。
for (i=0; i<arr_size; i++)
val ^= my_array[i];
私は2つの問題を観察しました:
- バージョン 1 のパフォーマンスは同じです。
- バージョン 2 は30% 以上向上しています。
- もっと良くなるように書き直すことはできますか?どこで次のよう
my_array
に宣言されていますuint32_t my_array[BIG_LENGTH];
- 通常の xoring コードのパフォーマンスを向上させる非 NEON の方法はありますか? ループを展開しても改善されません。