0x9*_*x90 4 c optimization arm neon cpu-cache
试图xor一个巨大的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;
}
Run Code Online (Sandbox Code Playgroud)
版本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;
}
Run Code Online (Sandbox Code Playgroud)
将上述两个版本与传统的xor实现进行比较:
for (i=0; i<arr_size; i++)
val ^= my_array[i];
Run Code Online (Sandbox Code Playgroud)
我发现了两个问题:
my_array宣布为
uint32_t my_array[BIG_LENGTH];很可能这将是内存带宽有限 - 一旦你使可用的DRAM带宽饱和,这对于每个负载只有一个ALU操作应该很容易做到,你将无法从优化中获得任何进一步的好处.
如果可能的话,尝试将您的XOR与相同数据上的另一个操作结合起来 - 这样就可以分摊缓存未命中的成本.