【问题标题】:ARM Neon intrinsics, addition of two vectorsARM Neon 内在函数,两个向量相加
【发布时间】:2021-11-01 02:55:03
【问题描述】:

我有一个非常简单的 C 函数,成对添加两个整数数组:

void add_arrays(int* a, int* b, int* target, int size) {
    for(int i=0; i<size; i++) {
        target[i] = a[i] + b[i];
    }
}

我看到在 ARM 上,Neon 内在函数在 中可用,并且您应该能够添加、乘法等向量,但我看到的所有示例都非常复杂。有人可以展示如何使用 ARM Neon 内在函数执行简单的操作,例如成对加法吗?

更新 我的术语是错误的,我希望实现元素加法。

谢谢!

【问题讨论】:

  • 不是成对添加你需要的,

标签: c arm add hpc neon


【解决方案1】:

首先,正如 Jake 所说,这段代码的作用是不是成对加法。成对加法是添加相邻的对;像

void add_arrays(int* a, int* target, int size) {
    for(int i=0; i<size; i++) {
        target[i] = a[i * 2] + a[(i * 2) + 1];
    }
}

这可以使用 NEON 来完成,但我会假设您的代码是正确的,但对于此答案的其余部分,您的术语是错误的。如果情况相反,这个答案加上查看vpaddq_s32(或者vpaddl_s32)的文档应该可以让你大部分时间到达那里。

为简单起见,我将假设大小是 4 的倍数(因为 4 个 32 位元素 = 1 128 位向量),所以:

void add_arrays(int* a, int* b, int* target, int size) {
    for(int i=0; i<size; i+=4) {
        target[  i  ] = a[  i  ] + b[  i  ];
        target[i + 1] = a[i + 1] + b[i + 1];
        target[i + 2] = a[i + 2] + b[i + 2];
        target[i + 3] = a[i + 3] + b[i + 3];
    }
}

现在让我们添加一些 NEON 内在函数:

#include <arm_neon.h>

void add_arrays(int* a, int* b, int* target, int size) {
    for(int i=0; i<size; i+=4) {
        /* Load data into NEON register */
        int32x4_t av = vld1q_s32(&(a[i]));
        int32x4_t bv = vld1q_s32(&(b[i]));

        /* Perform the addition */
        int32x4_t targetv = vaddq_s32(av, bv);

        /* Store the result */
        vst1q_s32(&(target[i]), targetv);
    }
}

就是这样。您可以在https://godbolt.org/z/W6KPv186x 看到生成代码的不同之处。

【讨论】:

  • 谢谢!这正是我想要的!
  • 嘿@nemequ,我刚刚看到你是 simd-everywhere 的维护者!很酷!
猜你喜欢
  • 2013-09-16
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-03
  • 2013-09-18
  • 1970-01-01
  • 2014-05-06
相关资源
最近更新 更多