c - 优化 NEON XOR 实现

标签 c optimization arm neon cpu-cache

尝试异或一个巨大的 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. 版本 1 具有相同的性能。
  2. 版本 2 比 30% 好一点。

  1. 我可以重写它以使其更好吗?其中 my_array 声明为 uint32_t my_array[BIG_LENGTH];
  2. 是否有一种非 NEON 方法可以提高常规异或代码的性能? unrolling the loop没有任何改善。

最佳答案

这很可能是内存带宽受限 - 一旦您使可用 DRAM 带宽饱和,每次加载只需一个 ALU 操作就可以很容易地做到这一点,您将不会从优化中获得任何进一步的好处。

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

关于c - 优化 NEON XOR 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19163004/

相关文章:

android - 具有不同 native 代码的多个 APK

无法从 arduino 发送 RS-232 命令

c# - Webapi2-完成一项任务后从 Controller 操作返回,但继续进行进一步的异步处理

c - 当其中一个函数/宏在代码中时,Keil 创建 'faulty' hex 文件

c - STM32F3 Discovery - 实现 GPIO 中断

css - 将开发 CSS 中的导入合并到 1 个文件中以进行生产

c - 在这些条件下设置变量原子

c - 错误 : Conflicting types for 'remove'

c - 在 c 中取消引用指针的不同值

c - 使用 SSE : horizontal add and dot product - what's the point? 的高效 4x4 矩阵 vector 乘法