优化NEON XOR实施

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)

我发现了两个问题:

  1. 版本1具有相同的性能.
  2. 版本2的好几率超过30%.

  1. 我可以重写它甚至更好吗?在哪里my_array宣布为 uint32_t my_array[BIG_LENGTH];
  2. 是否有非NEON方式可以提高常规xoring代码的性能?展开循环并没有带来任何改进.

Pau*_*l R 5

很可能这将是内存带宽有限 - 一旦你使可用的DRAM带宽饱和,这对于每个负载只有一个ALU操作应该很容易做到,你将无法从优化中获得任何进一步的好处.

如果可能的话,尝试将您的XOR与相同数据上的另一个操作结合起来 - 这样就可以分摊缓存未命中的成本.