ARM architecture
ARM 浮点运算类型
低端 ARM 处理器没有独立的硬件浮点运算单元,需要软件来实现浮点运算;
高端 ARM 处理器基本都具备了硬件执行浮点操作的能力。
两个不同的嵌入式应用程序二进制接口(EABI)软浮点, 矢量浮点(VFP)。
但是软浮点(soft float)和硬浮点(hard float)之间有向前兼容却没有向后兼容的能力,也就是软浮点的二进制接口(EABI)仍然可以用于当前的高端 ARM 处理器。
FPU 单元
在 ARM 体系架构内核中,有些有浮点运算单元(fpu,floating point unit),有些没有。对于没有 fpu 的内核,是不能使用 armel 和 armhf 的。在有 fpu 的情况下,就可以通过 gcc 的选项 -mfloat-abi 来指定使用哪种,有如下三种值:
soft: 不用 fpu 计算,即使有 fpu 浮点运算单元也不用
armel:(arm eabi little endian)即 softfp,用 fpu 计算,但是传参数用普通寄存器传,这样中断的时候只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算
armhf:(arm hard float)也即 hard,用 fpu 计算,传参数用 fpu 中的浮点寄存器传,省去了转换,性能最好,但是中断负荷高
arm64: 64 位的 arm 默认就是 hard float 的,因此不需要 hf 的后缀
kernel、rootfs 和 app 编译的时候,指定的编译选项必须保持一致才行。
使用 softfp 模式,会存在不必要的浮点到整数、整数到浮点的转换,而使用 hard 模式,在每次浮点相关函数调用时,平均能节省 20 个 CPU 周期。对 ARM 这样每个周期都很重要的体系结构来说,这样的提升无疑是巨大的。在完全不改变源码和配置的情况下,在一些应用程序上,虽然 armhf 比 armel 硬件要求(确切的是指 fpu 硬件)高一点,但是 armhf 能得到 20-25% 的性能提升,对一些严重依赖于浮点运算的程序,更是可以达到 300% 的性能提升。
armel 与 armhf
旧的 EABI 中,armel(低端ARM硬件,支持 armv4 以上版本),在执行浮点运算之前,浮点参数必须首先通过整数寄存器,然后传递到浮点运算单元。新的 EABI,也就是 armhf,通过直接传递参数到浮点寄存器,优化了浮点运算的调用效率。相比我们熟悉的 armel,armhf 代表了另一种不兼容的二进制标准。
在一些社区的支持下,armhf 目前已经得到了很大的发展。像 Ubuntu,已经在新发行版 (>12.04) 中放弃 armel,转而支持 armhf 编译的版本。
安装 armel 和 armhf 编译支持
Ubuntu 系统下安装两种交叉编译器:
arm-linux-gnueabi 的安装sudo apt-get install gcc-arm-linux-gnueabi
arm-linux-gnueabihf 的安装,linaro 开源组织有相关的交叉工具
armhf 使用
armhf 的开启需要硬件的支持,在 Debian 的 Wiki 上要求 ARMv7 CPU, Thumb-2 指令集以及 VFP3D16 浮点处理器。在 gcc 的编译参数上,使用 -mfloat-abi=hard -mfpu=vfp 即可。
在工具上,CodeSourcery 最早支持 hard 模式。或者,也可已自己编译工具链。