使用NEON乘法累加在iOS(Using NEON multiply accumulate on i

2019-08-01 13:48发布

即使我一种编译armv7只,NEON乘法累加内在似乎被分解为单独的乘法和补充。

我已经通过6几种版本的Xcode到最新的4.5,与iOS的SDK 5遇到过,并用不同的优化设置,既有建筑通过Xcode和直接通过命令行。

例如,建筑和拆卸一些test.cpp

#include <arm_neon.h>

float32x4_t test( float32x4_t a, float32x4_t b, float32x4_t c )
{
   float32x4_t result = a;
   result = vmlaq_f32( result, b, c );
   return result;
}

clang++ -c -O3 -arch armv7 -o "test.o" test.cpp
otool -arch armv7 -tv test.o

结果是

test.o:
(__TEXT,__text) section
__Z4test19__simd128_float32_tS_S_:
00000000    f10d0910    add.w   r9, sp, #16 @ 0x10
00000004        46ec    mov ip, sp
00000006    ecdc2b04    vldmia  ip, {d18-d19}
0000000a    ecd90b04    vldmia  r9, {d16-d17}
0000000e    ff420df0    vmul.f32    q8, q9, q8
00000012    ec432b33    vmov    d19, r2, r3
00000016    ec410b32    vmov    d18, r0, r1
0000001a    ef400de2    vadd.f32    q8, q8, q9
0000001e    ec510b30    vmov    r0, r1, d16
00000022    ec532b31    vmov    r2, r3, d17
00000026        4770    bx  lr

而不是预期的使用vmla.f32

我在做什么错吗?

Answer 1:

它可以是一个错误或LLVM,铛的优化。 或器armcc GCC产生VMLA如您所愿,但如果你读的Cortex-A系列程序员指南V3,它说:

20.2.3调度

在某些情况下可以有相当大的延迟,特别是VMLA乘法累加(对于整数五个周期;七个周期为浮点)。 使用这些指令的代码应该优化,以避免试图使用结果值之前,它已准备好,否则会出现失速。 尽管有几个周期导致的延迟,这些指令做完全流水线这样几个操作可以在飞行一次。

因此,它是有道理的,LLVM-铛到VMLA分成乘法和累加注入该管道。



Answer 2:

霓虹灯乘加指令执行操作

c = c + a * b

需要注意的是信源的目的地,一个是相同的。 如果要执行的操作

d = c + a * b

编译器必须把它分解成两个指令

d = c
d = d + a * b

替代方案,它可以分解成乘法+加指令

d = a * b
d = d + c

在Cortex-A8的/ A9两种变体具有相同的吞吐,但对Cortex-A8的第二个变体具有更低的延迟,因为乘加指令导致摊位在许多情况下。



文章来源: Using NEON multiply accumulate on iOS