关于性能:非规范化数字 – IEEE 754浮点数

Denormalized Numbers - IEEE 754 Floating Point

因此,我试图了解更多关于非规范化数字的信息,如IEEE754浮点数标准中所定义的。由于谷歌的搜索结果,我已经阅读了好几篇文章,我还浏览了几篇StackOverflow文章。但是我还有一些问题没有回答。

首先,回顾一下我对非规范化浮动是什么的理解:

Numbers which have fewer bits of precision, and are smaller (in
magnitude) than normalized numbers

本质上,非规范化浮点具有表示任何浮点值都可能表示的最小(数量级)数字的能力。

听起来对吗?还有别的吗?

我读过:

using denormalized numbers comes with a performance cost on many
platforms

对此有何评论?

我也读过其中一篇文章

one should"avoid overlap between normalized and denormalized numbers"

对此有何评论?

在IEEE标准的一些介绍中,当提供浮点范围时,将排除非规范化值,并将表标记为"有效范围",几乎就像演示者在思考"我们知道非规范化数字可以表示尽可能小的浮点值,但由于规范化的数字,我们选择从更适合常用场景的范围中排除它们——就像不常用非规范化的数字一样。

我想我只是一直觉得使用非规范化的数字在大多数情况下不是件好事?

如果我必须自己回答这个问题,我会想:

使用非规范化的数字是很好的,因为您可以表示尽可能小的(数量级)数字——只要精度不重要,并且不将它们与规范化的数字混合,并且应用程序的结果性能符合要求。

使用非规范化的数字是一件坏事,因为大多数应用程序不需要这么小的表示——精度损失是有害的,并且您可以通过将它们与规范化的数字混合在一起太容易让自己陷入困境,而且在大多数情况下,性能不值得付出成本。

对这两个答案有何评论?对于非规范化的数字,我还可能遗漏或不了解什么?


Essentially, a denormalized float has the ability to represent the
SMALLEST (in magnitude) number that is possible to be represented with
any floating point value.

没错。

using denormalized numbers comes with a performance cost on many platforms

在不同的处理器上,惩罚是不同的,但可以达到2个数量级。原因是什么?与本建议相同:

one should"avoid overlap between normalized and denormalized numbers"

关键是:非规范化是一种固定点的"微格式",在IEEE-754浮点格式中。在正常数字中,指数表示二进制点的位置。非正规数包含定点表示法中的最后52位,双精度数的指数为2-1074。

因此,非规范化处理很慢,因为它们需要特殊的处理。在实践中,它们很少发生,芯片制造商不喜欢在罕见的情况下花费太多有价值的资源。

将非正规与正规混合是很慢的,因为这样您就混合了格式,并且有了在这两者之间转换的额外步骤。

I guess I just keep getting the impression that using denormalized
numbers turns out to not be a good thing in most cases?

非规范化是为一个主要目的而创建的:逐渐下溢。这是一种保持微小数字之间相对差异小的方法。如果从最小的法向数直接变为零(突然下溢),则相对变化是无限的。如果在下溢时进行非正规化,相对变化仍然不完全准确,但至少更合理。这种差异在计算中显示出来。

换一种说法。浮点数分布不均匀。两个数的连续两次幂之间总是有相同数量的数:252(用于双精度)。因此,如果没有非正规化,最终的结果总是在0和最小的浮点数之间有一个间隙,这个间隙是最小两个数之差的252倍。非正规化均匀地填补这个空白。

作为一个关于突然下溢和逐渐下溢影响的例子,看看数学上等价的x == yx - y == 0。如果xy很小但不同,并且使用了突然下溢,那么如果它们的差小于最小截止值,那么它们的差将为零,因此违反了等价性。

随着逐渐下溢,两个微小但不同的正常数之间的差会变成一个非正常值,它仍然不是零。等价性保持不变。

因此,不建议故意使用非规范化,因为它们只是在特殊情况下作为备份机制设计的。