为什么从硬件架构角度讲,反规范化浮点数比其他浮点数慢那么多?

17

非规范化数比规范化数慢得多,大约慢100倍左右。这常常导致意外的软件问题

从CPU架构的角度来看,我很好奇,为什么非规范化数要慢那么多呢?这种性能缺失是与它们的不幸表示方式有关吗?还是CPU架构师忽略了它们,以减少硬件成本,错误地认为非规范化数无关紧要?

如果是前者,如果非规范化数在硬件上固有的不友好,是否存在已知的非IEEE-754浮点表示,也靠近零但对于硬件实现更方便?


7
非正常数需要额外的归一化处理(输入时)和反归一化处理(输出时)。一些处理器架构为了以全速处理这些数据,会花费额外的硬件(移位器加控制逻辑),例如NVIDIA GPU。其他处理器架构则通过微码实现内部异常处理来处理非正常数,例如大多数x86 CPU,这样可以节省硬件但速度较慢。后一种方法的理由是能够快速处理频繁出现的情况,并使用最少的硬件开销正确地处理不常见的情况(例如无穷大、NaN、非正常数)。 - njuffa
1
@njuffa:为什么不把那个作为答案呢? - Simon Byrne
2
E.M. Schwarz, M. Schmookler和S.D.Trong的论文题为“非规格化数的硬件实现”,发表于2003年6月15日举办的第16届IEEE计算机算术研讨会上,页码为70-78。(在线版本 - njuffa
1
请注意,我说的是“大多数x86 CPU”。甚至在同一处理器内可能会有所不同:原始的AMD Athlon处理器在读取路径中具有对非规格化数的硬件支持(通过动态延长流水线;这上面有一个专利),但在存储路径中具有对非规格化数的微码异常处理程序(以避免非规格化数支持的开销减慢存储到加载转发路径的常见情况下的速度)。 - njuffa
1
处理涉及零、无穷大和NaN的特殊情况通常由特殊硬件(例如各种AMD x86处理器)执行,这与处理非规格化数的问题略有不同,因为硬件开销可以保持相当小,并涉及通常不影响流水线长度的并行硬件路径,而非规格化数处理通常会影响流水线长度(增加长度)。 - njuffa
显示剩余4条评论
2个回答

9
在大多数x86系统上,性能较慢的原因是非规格化的值会触发FP_ASSIST。这个过程非常昂贵,因为它会切换到一个类似于错误处理的微代码流程中。(与故障非常相似)。
例如 - https://software.intel.com/en-us/forums/intel-performance-bottleneck-analyzer/topic/487262 之所以这样做,可能是因为架构师们决定通过猜测每个值都被规格化(这将更为常见),来优化正常值的硬件,并不想因为罕见的特殊情况而牺牲频繁使用情况的性能。这种猜测通常是正确的,所以只有在你猜错时才会付出代价。这些权衡在CPU设计中非常常见,因为在一个情况中的任何投资通常会给整个系统增加开销。
在这种情况下,如果你要设计一个尝试优化所有类型的不规则FP值的系统,你将不得不添加一些用于检测并记录每个操作后每个值的状态的硬件(这将乘以物理FP寄存器、执行单元、RS条目等的数量,总计产生大量的晶体管和导线)。
或者,你需要添加一些机制来检查读取的值,这将在读取任何FP值时都会减慢速度(即使是规格化值)。
此外,根据类型,您需要执行某些更正操作或不执行-在x86上,这就是辅助代码的目的,但如果您没有做出猜测,那么您将不得不有条件地对每个值执行此流程,在常见路径上已经增加了大量的开销。

2
检测读取时的非规格化数难道不是很便宜吗?全零指数和非零尾数?我猜生成它仍需要几个门延迟,但我认为真正的成本在于实现非规格化数处理的硬件。如果您有正常和非规格化数处理硬件,两者都可以并行工作,并且一旦您的非规格化数检测器选择了结果,您可以从其中一个中获取结果。 - Peter Cordes
关于在寄存器中标记FP值等问题:例如,当使用mulps指令的输出作为mulpd指令的输入时,Agner Fog发现在AMD CPU上会出现大的延迟。他猜测AMD CPU会对FP向量的元素进行标记(并且当错误代码导致错误预测时会变慢)。 - Peter Cordes
@PeterCordes,就像我说的那样,这个检查很简单,但即使在硬件中完成,仍然需要条件检查或(如果我们按照你的想法)预测执行,两者都可能会有惩罚。我想这是一个设计决策,我们永远不会知道(除非看到实际的微代码)。 - Leeor
然而,这是一个一贯被做出的设计决策;我所知道的所有架构都对非规格化数有巨大的性能惩罚。似乎应该有一些与架构无关的原因。 - Sneftel
1
关于我之前的评论的更新:将次规范数作为流水线FP执行单元的一部分处理不会影响吞吐量,但可能会影响延迟。CPU通常关心延迟,因为依赖链可能成为瓶颈。GPU专为高度并行问题而设计,并只需使管道更长以处理次规范数。(一些现代x86 CPU可以处理某些情况下的次规范数,例如SnB系列用于加法/减法。)此外,njuffa在后来的重复问题为什么非规范化浮点值处理速度较慢?中的回答也很有参考价值。 - Peter Cordes

3

在许多架构中,浮点数的denormals(非规格化数)不会被FPU(硬件)处理 - 这意味着实现需要由软件来完成。

这里有一个很好的基本介绍:https://en.wikipedia.org/wiki/Denormal_number

在性能问题下 -


1
有哪些这样的架构的例子?例如,听起来x86不在其中。 - Nate Eldredge
1
大多数现代架构都通过硬件处理非规格化数值(denormals),包括x86架构。早期的RISC芯片往往不支持非规格化数值,但最新版本的ARM肯定支持。 - Simon Byrne
2
许多架构所做的是在微码中处理次规范数。这比在软件中处理它们更快速和简单。 - Pascal Cuoq
2
Alex,我知道那个;我的问题不是关于那是否正确,而是为什么会这样。CPU 架构师们为什么要在硬件中只实现普通数值并冒着巨大的减速风险,例如某些信号处理软件的 10 倍减速?为什么在硬件中同时实现正常数值和非规格化数值如此困难? - Michael
3
@dwelch说:denormal并不是“边角案例”。信号处理人员已经多次注意到,由于denormal的处理,“静默”可能会使系统崩溃,因为静默主要由denormal输入组成,而CPU则无法处理。这是一个真正的问题,而不是理论上的问题。 - Michael
显示剩余2条评论

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