Arm Neon本征函数,两个向量相加 [英] ARM Neon intrinsics, addition of two vectors

查看:21
本文介绍了Arm Neon本征函数,两个向量相加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的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上,<;arm_neon.h>;中提供了Neon内部函数,您应该能够进行加法、乘法等向量运算,但我看到的所有示例都非常复杂。谁能展示一下如何用ARM霓虹灯做一些简单的事情,比如两两相加?

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

谢谢!

推荐答案

首先,正如杰克提到的,此代码所做的是而不是两两相加。成对加法是将相邻的对相加;类似于

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];
    }
}

现在让我们添加一些霓虹灯本征:

#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查看生成代码的差异。

这篇关于Arm Neon本征函数,两个向量相加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆