【ARM 浮点计算单元 FPU (FPA,VFP,NEON)介绍】

文章目录
1.1 ARM FPU 简介
1.1.1 单精度浮点数
1.1.2 双精度浮点数
1.1.3 指数与尾数的特殊情况
1.1.4 IEEE 754 标准
1.2 编译器对浮点数的影响
1.2.1 VFP 和 FPA 的关系
1.2.1.1 VFP的功能特点
1.2.2 GCC 与浮点运算
1.2.3 VFP 现场保护
1.2.4 硬浮点与软浮点
1.3 ARM NEON
1.1 ARM FPU 简介
ARM 的 FPU(浮点单元)是ARM处理器的一个重要组成部分,主要负责执行浮点数运算。ARM 的 FPU支持IEEE 754标准的浮点数格式,并能够执行各种浮点数的基本运算,如加法、减法、乘法、除法等,以及一些更复杂的运算,如平方根、绝对值等。

在早期的ARM处理器中,浮点单元是一个可选的组件。但是在现代的ARM处理器中,如Cortex系列处理器,浮点单元通常是内置的,对于执行浮点数运算有极大的帮助。

另外,ARM的浮点单元还支持向量运算,能够同时处理多个浮点数,从而极大地提高了运算效率。这对于执行复杂的科学计算和图形处理等任务非常有用。

FPv5 是第五代的ARM浮点硬件。它支持所有的标准单精度浮点运算,包括加法、减法、乘法、除法、平方根和所有的比较运算。它也支持浮点到整数的转换,以及对浮点数的取整操作。

1.1.1 单精度浮点数
ARM32架构支持 IEEE 754标准的浮点数格式。在这个标准中,单精度(32位)和双精度(64位)浮点数的表示方法如下:
符号位(Sign):1bit,(bit[31]), 0代表正数,1代表负数。
指数位(Exponent):8bits (bit[30-23]), 用于表示浮点数的指数部分,通过偏移量127进行编码。
尾数位(Fraction/Mantissa):23bits,(bit22:0]), 表示浮点数的尾数部分,这部分直接决定了浮点数的精度。


单精度(32位)浮点数:

最小正数(非零)约为1.4E-45
最大正数约为3.4E38
有效位数约为7位十进制数
精度主要取决于尾数部分的位数,例如 float 尾数为 23位,除去尾数全部为 0 的情况以外,最小为 2-23 次方,约等于1.19 乘以10-7次方,所以 float 小数部分只能精确到后面6位。加上小数点前的一位,即有效数字为7位。

1.1.2 双精度浮点数
符号位:1bit,bit[63], 0 代表正数,1代表负数。
指数位:11bits,bit[62:52], 用于表示浮点数的指数部分,通过偏移量1023进行编码。
尾数位:52bits,bit[51:0], 表示浮点数的尾数部分,这部分直接决定了浮点数的精度。


双精度(64位)浮点数:

最小正数(非零)约为5.0E-324
最大正数约为1.8E308
有效位数约为15~16位十进制数
类似,double 尾数部分52 位,最小为2-52,约为 2.22 x 10-16,所以精确到小数点后15位,有效位数为16位

1.1.3 指数与尾数的特殊情况
在 ARM 单精度浮点数格式中,如果指数部分全为0或全为1,那么这将表示一些特殊情况。

指数部分全为0:

当尾数部分也全为0时,这表示的是正负零。
当尾数部分不为0时,这表示的是规格化的浮点数,也就是说这个数太小,无法用标准形式表示。
指数部分全为1:

当尾数部分全为0时,这表示正负无穷大。
当尾数部分不为0时,这表示非数(NaN)。
这些特殊情况是为了处理一些运算结果无法用常规浮点数表示的情况,比如除以零的结果是无穷大,0除以0或者无穷大减去无穷大的结果是非数等等。

1.1.4 IEEE 754 标准


1.2 编译器对浮点数的影响
1.2.1 VFP 和 FPA 的关系
ARM VFP(Vector Floating Point)和 FPA(浮点加速器)都是ARM架构中用于处理浮点数运算的硬件单元,可以加速浮点数的计算,比如加法、减法、乘法、除法等。

FPU可以看作是它的一个更普遍的术语。FPU可以是任何执行浮点运算的硬件,包括FPA和更现代的硬件,如VFP(向量浮点运算单元)和NEON。

FPA是较早的浮点处理单元,可以处理单精度和双精度浮点数。FPA有32个浮点寄存器,可以被组织为8个四元素向量,也可以用作单元素寄存器。

VFP是后来引入的,可以处理单精度、双精度和半精度浮点数,提供更强大的功能和更高的效率。VFP有32个64位寄存器,可以被视为32个双精度寄存器,或者64个单精度寄存器。

简单来说,VFP是FPA的升级版,提供了更高级的浮点计算支持。虽然两者的功能有所重叠,但是由于历史原因,它们在某些指令和寄存器组织方面存在差异。在实际应用中,需要根据特定的处理器和需求选择使用哪个。

1.2.1.1 VFP的功能特点
VFP 除了提供浮点数基本运算(加、减、乘、除、开方、比较、取反)提供支持之外,最有特点是它向量(vectors)功能。
它同时支持最多 8组单精度 4组双精度浮点数的运算。也可以通过协处理器 CP10 和 CP11来实现 VFP。其中 CP10 支持单精度浮点操作,CP11支持双精度浮点操作。所以所有的 VFP指令其实就是一些协 处理器的指令比如FADDS其实就是一个CDP指令,一个FLDS就是一个LDC指令。

1.2.2 GCC 与浮点运算
当使用GCC编译ARM程序时,你可以使用 -mfloat-abi 和 -mfpu 选项来设置浮点 ABI 和 FPU 类型。

-mfloat-abi 选项有三个可能的值:soft、softfp 和 hard。

soft表示所有浮点运算都由软件库来处理,没有使用硬件FPU;
softfp表示浮点运算使用硬件FPU,但浮点函数参数和返回值通过整数寄存器传递;
hard表示浮点运算使用硬件FPU,并且浮点函数参数和返回值通过FPU寄存器传递。
-mfpu 选项用于选择具体的 FPU 类型。对于VFP,有几种可能的值,例如vfp、vfpv3、vfpv4等,这取决于你的处理器支持哪种版本的VFP。

例如,如果你的处理器支持VFPv3,你可以使用如下的GCC选项来编译你的程序:

gcc -mfloat-abi=hard -mfpu=vfpv3
1
这样,GCC就会生成使用VFPv3硬件加速的浮点运算代码,并且使用FPU寄存器来传递浮点函数参数和返回值。

1.2.3 VFP 现场保护
在操作系统中,VFP(向量浮点运算单元)的状态是进程现场的一部分。当操作系统进行上下文切换时,需要保存和恢复VFP的状态。也就是说,操作系统需要保存当前运行的进程或线程的VFP寄存器的值,并在切换回来时恢复这些值。

对于支持硬件浮点运算的系统,这是非常重要的,因为如果不正确地保存和恢复VFP的状态,可能会导致浮点运算的结果错误。因此,操作系统需要确保在进程切换时正确处理VFP现场,以保证系统的正确运行。

1.2.4 硬浮点与软浮点
硬浮点
编译器将代码直接编译成硬件浮点协处理器(浮点运算单元FPU)能识别的指令,这些指令在执行的时候ARM核直接把它转给协处理器执行。FPU 通常有一套额外的寄存器来完成浮点参数传递和运算。使用实际的硬件浮点运算单元(FPU)会带来性能的提升。

软浮点
编译器把浮点运算转成浮点运算的函数调用和库函数调用(即用整数运算模拟浮点运算),没有FPU的指令调用,也没有浮点寄存器的参数传递。浮点参数的传递也是通过ARM寄存器或者堆栈完成。现在的 Linux 系统默认编译选择使用 hard-float, 如果系统没有任何浮点处理器单元,这就会产生非法指令和异常。因而一般的系统镜像都采用软浮点以兼容没有VFP的处理器。

1.3 ARM NEON
ARM NEON是ARM处理器中的一种高级SIMD(单指令多数据)的架构扩展,用于加速多媒体和信号处理计算。NEON可以支持8、16、32和64位整数和单精度(32位)浮点运算,并且可以处理多达16个操作数的并行运算。

NEON架构有32个128位寄存器,可用于整数和浮点运算,并且可以按需划分为更小的寄存器。这些寄存器可以在一条指令中处理多个数据,从而大大提高处理器处理多媒体数据的速度和效率。

ARM NEON集成在许多ARM Cortex-A系列处理器中,包括Cortex-A8、A9、A15等。此外,NEON也被广泛应用在视频编解码、图形处理、语音和音频处理等多媒体应用中。

可以使用Neon对算法加速。其实内核中的加密算法基本都是了Neon加速,如sha1、sha2…sha512、aes、chacha20等
————————————————
版权声明:本文为CSDN博主「CodingCos」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_32960911/article/details/127773859

猜你喜欢

转载自blog.csdn.net/u012294613/article/details/132322281
FPU