无法使用 ARM NEON 内在函数设置 4 个 floatx32 的向量

Posted

技术标签:

【中文标题】无法使用 ARM NEON 内在函数设置 4 个 floatx32 的向量【英文标题】:Can't set a vector of 4 floatx32 with ARM NEON intrinsics 【发布时间】:2016-08-16 15:55:38 【问题描述】:

我想从表中加载一些值并将它们设置为向量: 在第一种情况下,将向量的四个值设置为 a:

float32x4_t dest = vdupq_n_f32(a);

当我阅读内在函数手册时,这一点非常明显。

在第二种情况下,将向量的四个值设置为表中的不同值。这有点棘手,因为没有相关说明,所以我做了以下操作:

float32x4_t dest = a3,a2,a1,a0;

这不是内在的,但根据网络上的其他出版物和论坛,它是我唯一的解决方案。可悲的是,我收到了这个错误:

error: expected expression before ‘’ token

任何人都可以为此提供帮助或有替代方案吗?

【问题讨论】:

你用的是什么编译器?这应该适用于 gcc、clang 等。 ARM-gnueabi-gcc with eclipse Mars 【参考方案1】:

如果您的编译器不支持这样的直接初始化(即您使用的不是 gcc 或 clang),那么您需要显式加载值,例如

const float init[4] = a3,a2,a1,a0;
float32x4_t dest = vld1q_f32(init);

请注意,您的第一个示例似乎是错误的 - 如果您尝试将所有 4 个矢量元素设置为相同的值(如 SSE 的 _mm_set1_ps),那么您将需要使用类似 vdupq_n_f32 的东西。

【讨论】:

啊,我正在寻求性能......像这样所有其他指令将等到 init 数组被填充然后加载到 dest 通常这种向量初始化只进行一次,例如在函数开始时,在任何性能关键循环之前,所以这里或那里的几个循环应该对性能没有影响。如果您查看为例如生成的代码_mm_set_ps 你会看到它通常会导致许多指令(不要误以为所有内在函数都映射到单个指令)。 @A.nechi 最终,无论您选择如何用 C 来表达它,给定固定宽度的 32 位指令编码,您永远不会将 128 位任意数据放入寄存器中几个指令和/或内存访问。如果a0a1 等表示任意散布的东西,如果没有临时副本就无法连续,那么考虑通过直接使用vld1q_lane_f32() 加载它们来显式构建向量。 您可能想查看DirectXMath 以了解各种功能的一些并行 SSE 与 ARM-NEON 实现。对于“向量常量”,库使用XMVECTORF32 类型并且通常将它们声明为static const。这意味着它们是从只读数据段加载的,但这是在 SSE 或 ARM-NEON 中加载任意向量的更快方法之一。如果您为所有通道设置单个值,那么vdupq_n_f32 是一个不错的选择(唉,SSE 没有比_mm_set_ps1 更好的组合)。 注意:AVX 确实有 _mm_broadcast_ss,它相当于 ARM-NEON vld1q_dup_f32,它至少消除了由 _mm_load_ps1_mm_set_ps1 复合内在函数添加的洗牌。

以上是关于无法使用 ARM NEON 内在函数设置 4 个 floatx32 的向量的主要内容,如果未能解决你的问题,请参考以下文章

ARM NEON 没有 xor gcc 内在函数

如何使用 ARM Neon 内在函数对 IF 块进行矢量化?

使用NEON优化ARM的卷积运算

使用 ARM neon 内部函数进行深度转换

二进制图像上的快速像素计数 - ARM neon 内在函数 - iOS 开发

如何在 ARM NEON SIMD 内在函数上编写“a[i]=b[c[i]]”