7

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

对于这三种类型,说乘法的性能如何:

  1. IEEE 浮点 (32)
  2. 具有 16 位有符号值和有符号 16 位指数的自定义 32 位浮点类
  3. 32 位固定十进制

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

任何帮助将不胜感激!

4

1 回答 1

9

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

  • +/-无穷大输入
  • 输入中的非数字
  • +/-0 输入
  • 输入中的规范化与非规范化数字以及尾数中的隐式“1”
  • 拆箱包装
  • 规范化/非规范化
  • 不足和溢出检查
  • 正确的舍入,这可能导致额外的(反)规范化和/或下溢/溢出

如果您将上述内容粗略地算作一些原始微操作(列表中的每个项目为 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

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

十进制数十六进制表示法  
(尾数 x Exp)  
0.9999998 x 2 127      7FFFFF 7F  
0.5 x 2 127    400000 7F  
0.625 x 2 4    500000 04  
0.5 x 2 1      400000 01  
0.5 x 2 0      400000 00  
0.5 x 2 -1     400000 法郎  
0.5×2 -128   400000 80  
0.0 x 2 0      000000 00  
-1.0 x 2 0     800000 00  
-0.5000001 x 2 -128    BFFFFF 80  
-0.7500001 x 2 4   9FFFFF 04  
于 2013-01-26T09:24:31.873 回答