试图对一个巨大的uint32
数组进行异或运算,我决定使用 NEON 协处理器。
我实现了两个c
版本:
版本 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%以上。
- 我可以重写它以更好吗?where
my_array
被声明为uint32_t my_array[BIG_LENGTH];
- 有没有一种非 NEON方法可以提高常规 xoring 代码的性能?展开循环并没有带来任何改进。