ARM指令集——浮点运算

ARM汇编语言

浮点运算

IEEE-754定义和运算基础

版本更新:

  • 1985
  • 2008:添加了精确控制

IEEE定义了可行的舍入方法,以及所有运算结果和异常。

舍入方法:向上/向下/向0/最近

运算异常:过大,过小,不准确,非法,除以零

异常处理:Not a Number(NaN),正负无穷,“denormalized number”

表示方法

单精度为32位,双精度为64位,VFP在硬件上支持二者。VFPv2额外支持半精度。

存储结构:

  • 符号bit
  • 指数位
  • 二进制小数

表示的数字是:$sm2^{exp}$

二进制小数部分表示的小数被翻译为1.xxxx中xxx部分,如果数字是0则设置所有指数位为0。

具体含特殊值的表示表格

指数(默认偏移-127) 尾数 含义
-127 0 +=0
-127 !=0 非正常数
128 0 正负无穷
128 !=0 NaN
Other Any $(+/-)1.*2^{}$

非正常数,按照标准应当表示前导1改为前导0的极小数,从而表示更小的数字,但是由于真实场景下通常不需要计算,故可能被忽略,但这是违反规范的。Cortex的VFP可以通过设置修改计算表现。

舍入规范

舍入方面,最近舍入如果距离相等,向舍入后最低有效位为0的方向舍入。2008版本标准添加了总是向0的模式,Armv7此时的Cortex尚未支持。

VFP

该扩展是可选的,但通常被实现,由16/32个双字寄存器实现。VFPv3-D32和VFPv3-D16用来标记这两种实现。如果NEON同时实现,则选用D32。

VFPv3可选提供了浮点转换,在16/32位之间进行转换。

VFPv4在v3基础上添加了半精度扩展和融合的乘加指令。乘加指令只有一次舍入,这也是2008规范的一个内容,提高了重复累计操作的计算精度。

寄存器

  • FPSID:记录硬件支持的浮点特性
  • FPSCR:status and control,记录比较结果和异常标记,控制位设置舍入和使能浮点异常陷入
  • FPEXC:记录异常情况
  • MVFR0/MVFR1:记录硬件对于SIMD和浮点特性的支持。

用户模式下只能访问FPSCR,Linux下通过/proc/cpuinfo获知系统支持的特性。

由于浮点比较使用FPSCR,故在整数中使用前需要使用VMRS指令将FPSR转移到APSR中。

比较结果定义

结果 N Z C V
= 0 1 1 0
LT 1 0 0 0
GT 0 0 1 0
NaN 0 0 1 1

指令使用

绝大多数不能用立即数。VCMP可以用0进行比较。

系统支持

linux下,为了节省周期,软件第一次访问VFP时系统会进行初始化。对于线程可以被迁移到不同核心的集群上,这种机制受限于核心可能变换,故不会非常有效。

优化

  • 避免在Cortex-A9上昏庸NEON和VFP,因为在两者间切换时开销很大
  • 对于FPSCR的存取性能消耗显著
  • 整数-浮点寄存器之间的转移开销明显。
  • 多个单独存取操作最好合并为一个,从而最大化利用带宽。
Licensed under CC BY-NC-SA 4.0
京ICP备2021032224号-1
Built with Hugo
主题 StackJimmy 设计
vi ./themes/hugo-theme-learn/layouts/partials/footer.html