Arm 如何在neon中添加标量?

Arm 如何在neon中添加标量?,arm,simd,neon,Arm,Simd,Neon,我想用标量做加法。以下是我尝试过的: ex) uint32x4_t result, result2, op, one; // op + 1 result = vaddq_u32(op, 1); //error, 1 is not vector one = vdupq_n_u32(1); result2 = vaddq_u32(op, one); // ok 执行此操作时,节省内存空间的最佳方法是什么?没有关于矢量标量alu类型操作的指令,在NEON上只有>=16位宽度的乘法 也没有按即

我想用标量做加法。以下是我尝试过的:

ex) uint32x4_t result, result2, op, one;

// op + 1

result = vaddq_u32(op, 1); //error, 1 is not vector

one = vdupq_n_u32(1);

result2 = vaddq_u32(op, one); // ok

执行此操作时,节省内存空间的最佳方法是什么?

没有关于矢量标量alu类型操作的指令,在NEON上只有>=16位宽度的乘法

也没有按即时值添加/细分的说明

你已经做的是你应该做的

可以尝试提高性能的一件事是在循环外将1的向量声明为常量,希望编译器足够聪明,不会在循环内的每次迭代中反复加载相同的值


不幸的是,在NEON方面,可用的ARM编译器并不那么可靠。检查反汇编是非常必要的,这首先就破坏了在intrinsic中编写的要点。

可以乘以标量,但不能相加。复制一个值然后添加它不是什么大问题。NEON能有效地生成所有值的向量吗?如果是,则执行该操作,然后减去它以添加
1
。(在x86 SSE2中,这将是
pcmpeqd xmm1,xmm1
(所有的,对大多数CPU没有错误依赖),
psubd xmm0,xmm1
)。我不建议尝试实际使用compare-same,在C中使用intrinsic;相反,请编写
vdupq\u n\u u32(-1)
,这样编译器就可以动态生成常量作为优化(同样,如果NEON能够有效地这样做的话)。谢谢。我们以后应该用老办法来做。@PeterCordes记住ARM要求为内存排序保留依赖项,所以那种破坏x86依赖项的习惯用法不起作用。然而,ARM NEON有即时指令(VMOV、VORR、带即时的VBIC)和相应的内部指令:
uint32x2\t vcreate\u u32(uint64\u-code>)、
int32x2\t vcreate\u s32(uint64\u-code>)和
aarch64
上的
VMOV
可以分配即时值,一条单周期指令。我知道编译器使用ARM内部函数(与x86或PowerPC Altivec相比)时非常糟糕(经常达到无法使用的程度),但它们真的如此糟糕以至于可能无法将向量常量创建从循环中提升出来吗?@PeterCordes他们简直太糟糕了。编写intrinsics并验证反汇编比简单地编写汇编代码要花费更多的时间。后一个作业在其他工具链和版本上变得无用。我的意思是用“后一个作业”验证和修改内部代码