IEEE浮点数与自定义浮点数性能

Rya*_*own 7 c++ floating-point fixed-point

我正在处理没有浮点单元的处理器,所以我必须为用户界面使用固定或自定义浮点类型.

对于这三种类型,表示乘法的表现如何:
1.IEEE Float(32)
2.自定义32位浮点类,带有16位有符号值和带符号的16位指数
3. 32位固定小数

我想要一些可扩展到具有浮点单元的处理器的东西,自定义浮点数是否具有IEEE浮点数的竞争性能?我听说IEEE浮点数在没有FPU的处理器上的性能很糟糕,是因为由于24位值不是原生的,它必须做疯狂和/或?也就是说,自定义浮点类会缓解性能问题吗?

任何帮助将不胜感激!

Ale*_*nze 9

由于需要检查和正确处理的许多边缘情况,软件模拟的IEEE浮点/双精度很慢.

  • 输入+/-无穷大
  • 输入中的非数字
  • 输入+/- 0
  • 输入中的归一化vs非规范化数字和尾数中隐含的"1"
  • 打开包装
  • 归一化/反规范化
  • 欠检和溢出检查
  • 正确的舍入,这可能导致额外(de)标准化和/或下溢/溢出

如果你只是粗略地将上面的数量计算为一些原始的微操作(列表中的每个项目为1),你就会接近10.在最坏的情况下会有更多.

因此,如果您对IEEE编译浮点运算感兴趣,那么期望每个模拟操作都比它的整数运算慢30倍(CodesInChaos的注释是及时的,每个加法/乘法38个时钟).

您可以通过选择浮点格式来剪切一些角点:

  • 只有一个零
  • 没有非数字
  • 仅归一化数字
  • 尾数中没有隐含的"1"
  • 指数和尾数各占一个整数个字节
  • 没有或原始的舍入
  • 可能,没有无限
  • 可能是2的补码尾数
  • 可能,没有指数偏见

定点运算可能会变得更加高效.但它常见的问题是你必须事先知道所有输入范围和中间结果,这样你才能选择正确的格式以避免溢出.您还可能需要支持多种不同的定点格式,例如16.16,32.32,8.24,0.32.C++模板可以帮助减少代码重复.

无论如何,你能做的最好的事情是定义你的问题,用浮点和定点算法求解它,观察哪两个最适合哪个CPU并选择胜利者.

编辑:有关更简单的浮点格式的示例,请查看MIL-STD-1750A的32位浮点格式:

 MSB                                         LSB MSB          LSB
------------------------------------------------------------------
| S|                   Mantissa                 |    Exponent    |
------------------------------------------------------------------
  0  1                                        23 24            31
Run Code Online (Sandbox Code Playgroud)

浮点数表示为分数尾数乘以指数幂的2倍.在浮点运算开始时,所有浮点数都被假定为归一化或浮点零,并且所有浮点运算的结果都被归一化(标准化浮点数具有尾数的符号,而下一位具有相反值)或浮点零.浮点零定义为0000 0000 16,即零尾数和零指数(00 16).扩展浮点零定义为0000 0000 0000 16,即零尾数和零指数.32位浮点数的机器表示的一些示例:

Decimal Number  Hexadecimal Notation  
(Mantissa x Exp)  
0.9999998 x 2127     7FFFFF 7F  
0.5 x 2127   400000 7F  
0.625 x 24   500000 04  
0.5 x 21     400000 01  
0.5 x 20     400000 00  
0.5 x 2-1    400000 FF  
0.5 x 2-128  400000 80  
0.0 x 20     000000 00  
-1.0 x 20    800000 00  
-0.5000001 x 2-128   BFFFFF 80  
-0.7500001 x 24  9FFFFF 04