你好,neon指令集中vfmaq_f32和vmlaq_f32有什么区别,运行速度和精度有什么区别
在 macOS ARM64 上,代码运行一致
#include<arm_neon.h>
#include<iostream>
using namespace std;
int main(){
float a = 12.3839467819;
float b = 21.437678904;
float c = 4171.42144;
printf("%.17f\n",a);
printf("%.17f\n",b);
printf("%.17f\n",c);
printf("%.17f\n",a+b*c);
float32x4_t a_reg = vdupq_n_f32(a);
float32x4_t b_reg = vdupq_n_f32(b);
float32x4_t c_reg = vdupq_n_f32(c);
float32x4_t res_reg = vfmaq_f32(a_reg, b_reg, c_reg);
float res[4] = {0.f};
vst1q_f32(res,res_reg);
printf("%.17f\n",res[0]);
res_reg = vmlaq_f32(a_reg, b_reg, c_reg);
vst1q_f32(res,res_reg);
printf("%.17f\n",res[0]);
res_reg = vmulq_f32(b_reg, c_reg);
res_reg = vaddq_f32(res_reg, a_reg);
vst1q_f32(res,res_reg);
printf("%.17f\n",res[0]);
return 0;
}
vfmaq_f32
定义为单个融合操作,而 vmlaq_f32
can 通过乘法然后累加来实现。
我想到了两种解释。首先,在某些时候,融合版本(
FMLA
指令)可能是可选指令(我不知道什么时候,而且我有点懒得去挖掘真正旧的文档)。第二种可能性似乎更有可能,那就是融合版本在某些时候可能会慢一些。
如今,编译器看起来几乎只是将两者编译为相同的指令,因此它实际上是一个别名,但如果您想要准确性,您可能仍然应该使用
vfmaq_f32
,但如果您对速度更感兴趣,则vmlaq_f32
.