软浮点硬浮点不配套问题(error:uses VFP register arguments)

1、前言

报错信息:

error:/home/xxx.a uses VFP register arguments,
/home/xxx.a does not

VFP(Virtual Float Point)是虚拟浮点运算,又分为硬件浮点数计算和软件浮点数计算。报错原因是一个库使用了硬件浮点数,另一个库没有使用,于是链接器在链接两个库文件时检查到两个库的浮点类型不匹配。

2、软浮点数(soft-float)

软件浮点数是利用库函数来进行浮点运算,不要求CPU有浮点运算相关的寄存器和浮点运算单元,因为是浮点库来运算所以在链接的时候要把浮点库链接进去:-lgcc。浮点数相较于硬件浮点数效率低,但是适配性好,不管CPU有没有浮点运算单元都可以。

3、硬浮点数(hard-float)

硬件浮点数就是用FPU(硬件浮点协处理器)进行浮点运算,将浮点运算编译成FPU能运行的指令,FPU通常有专门用于浮点运算的寄存器,使用硬件浮点计算会带来性能的提升,但前提是芯片要有FPU。

4、浮点运算的编译选项(-mfloat-abi=value)

在编译器中用"-mfloat-abi"选项指定浮点数运算方式,-mfloat-abi=soft是采用软件浮点运算;-mfloat-abi=hard是指定硬件浮点数,-mfloat-abi=softfp是兼容软件浮点运算的硬件浮点运算;在使用硬件浮点数时,还需要额外再指定FPU单元,通过-mfpu指定,比如-mfpu=vfp或者-mfpu=neno。
Linux系统默认编译选择使用hard-float,如果系统没有任何浮点处理器单元,这就会产生非法指令和异常。因而一般的系统镜像都采用软浮点以兼容没有VFP的处理器。
softfp,用fpu计算(即会将浮点运算编译成对应的浮点指令),但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。hard,用fpu计算,传参数用fpu中的浮点寄存器传,省去了转换性能最好,但是中断负荷高。

VFP & Neon

(1)VFP是一个按顺序工作的浮点协处理器, 它对一组输入执行一个操作并返回一个输出。目的是加快浮点计算,支持单精度和双精度浮点。
(2)Neon是SIMD (Single Instruction Multiple Data) , 支持单指令多数据操作,意味着在执行一条指令期间,将对多达16个数据集并行执行相同的操作,支持整数和单精度浮点数向量化(并行)操作。
(3)二者区别:VFP 支持单精度和双精度浮点,顺序执行,目的加快浮点计算。Neon 是SIMD,支持单指令多数据操作,支持整数和单精度浮点数向量化(并行)操作,不支持双浮点 。Neon最大的好处是如果想要执行矢量操作,如对视频的编码/解码, 它可以并行执行单精度浮点(float)操作。 从而提高对视频编码/解码性能。VFP 和Neon是共用浮点寄存器,只是执行的指令不同

5、解决步骤

5.1、确定当前是软/硬浮点数

在编译选项中,通过确定"-mfloat-abi"参数来查看当前采用的浮点运算方式;
(1)如果你有源码,直接去查看编译脚本确定;
(2)如果你只有编译好的库文件,比如.a文件获取.ko文件,尝试用文本编辑软件(natepad++)去打开,在里面查找编译选项的值;

5.2、重新指定编译采用的软/硬浮点数

修改编译选项"-mfloat-abi",使得两个库的浮点运算兼容,同时用软件浮点数或硬件浮点数。在使用硬件浮点数时要注意芯片是否有硬件浮点单元,否则会报错。

猜你喜欢

转载自blog.csdn.net/weixin_42031299/article/details/120837373