尝试异或一个巨大的 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个版本与传统异或实现的对比:
for (i=0; i<arr_size; i++)
val ^= my_array[i];
我发现了 2 个问题:
- 版本 1 具有相同的性能。
- 版本 2 比 30% 好一点。
- 我可以重写它以使其更好吗?其中
my_array
声明为uint32_t my_array[BIG_LENGTH];
- 是否有一种非 NEON 方法可以提高常规异或代码的性能? unrolling the loop没有任何改善。
最佳答案
这很可能是内存带宽受限 - 一旦您使可用 DRAM 带宽饱和,每次加载只需一个 ALU 操作就可以很容易地做到这一点,您将不会从优化中获得任何进一步的好处。
如果可能,尝试将您的 XOR 与对同一数据的另一个操作结合起来 - 这样您就可以分摊缓存未命中的成本。
关于c - 优化 NEON XOR 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19163004/