IEEE浮点数与自定义浮点数的性能比较

7

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

这三种类型在乘法方面的性能如何?

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

我希望得到一些可以扩展到具有浮点单元的处理器的东西,那么自定义浮点与IEEE浮点在性能方面是否有竞争力?我听说IEEE浮点在没有FPU的处理器上的性能非常低,是因为需要进行疯狂和/或运算,由于24位值不是本机的吗?也就是说,自定义浮点类是否能缓解这个性能问题?

任何帮助将不胜感激!


如果你想要与使用硬件浮点数的处理器兼容,那么你真的没有选择,对吧?否则,你已经按从慢到快的顺序列出了它们。你的软类型(任何一种)都比硬件类型慢。 - Marc Glisse
与硬件实现相比,软IEEE浮点数的速度相当缓慢。我不确定其他浮点表示法的速度会更快。例如,我的C#实现需要约38个时钟周期来完成加法/乘法运算。 - CodesInChaos
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 000016即幂次方和分数均为零的数(0016)。扩展浮点零定义为0000 0000 000016,即幂次方和分数均为零。以下是32位浮点数机器表示的一些例子:
十进制数   十六进制符号
(分数 x 幂次方)  
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  

所有这些废话有什么意义?程序员在整数上没有检查也能很好地工作,速度比检查某些东西是否超出范围(每次操作10倍,显然)更为重要,如果需要安全性,您可以自己检查,就像您可以检查整数一样。 - Ryan Brown
我猜你确实需要检查指数部分的溢出情况,以使其始终正常工作。不过我不确定还有什么其他问题。 - Ryan Brown
@RyanBrown 大多数都非常有用。它们使实现更加复杂,但不一定更慢。例如,尾数中的隐式1简化了大多数操作。请记住,浮点数是为硬件实现而设计的,而不是为软件仿真而设计的。 - CodesInChaos
即使在简单的情况下,您也需要进行多项检查。在加法/减法中,您不能像使用2的补码整数那样简单地添加/减去两个数字。您需要对齐尾数并调整指数,考虑符号,然后进行加法/减法,然后需要规范化结果的尾数并再次调整指数,并在结果的大小太小而无法用该格式表示时可能将结果设置为0。这一点单独就会使浮点加/减运算比2的补码整数加/减运算慢大约10倍。 - Alexey Frunze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接