通常情况下,消耗或产生非正态值的浮点值比其他值慢,有时要慢得多。
为什么是这种情况?如果是因为他们陷进了软件而不是直接在硬件中处理,就像在某些CPU上所说的那样,他们为什么要这样做呢?
发布于 2019-02-28 21:14:37
对于IEEE-754浮点,大多数操作数是规范化的浮点数字,处理器中的内部数据路径是为规范化操作数而构建的。附加指数位可用于内部表示,以使浮点操作数始终在数据路径内规范化。
因此,任何低于正常值的输入都需要额外的工作才能首先确定前导零点的数目,然后左移该值的意义,同时调整指数。一个不正常的结果需要正确地转移意义,并以适当的数量和四舍五入可能需要推迟到发生之后。
如果完全在硬件中解决,这种额外的工作通常需要额外的硬件和额外的流水线阶段:一个,甚至两个额外的时钟周期,每一个处理低于正常的输入和低于正常的输出。但是,典型CPU的性能对指令的延迟很敏感,并且花费了很大的精力来保持延迟。FADD、FMUL或FMA指令的延迟时间通常在3到6个周期之间,具体取决于实现和频率目标。
因此,增加50%的额外延迟来潜在地处理低于正常的操作数是没有吸引力的,更重要的是,因为在大多数用例中,低于正常操作数是罕见的。因此,使用“使公有情况快速,使不寻常的案例发挥功能”的设计理念,就有很大的动机将低于正常的操作数从“快速路径”(纯硬件)推进到“慢路径”(现有硬件和软件的结合)。
我参与了x86处理器浮点单元的设计,处理异常的常用方法是在需要处理这些异常时调用内部微代码级异常。这种低于正常的处理方式可能需要100个时钟周期。其中最昂贵的部分通常不是修复代码本身的执行,而是进入和退出微代码异常处理程序。
我知道具体的用例,例如数字信号处理中的特殊滤波器,在那里遇到异常是很常见的。为了快速支持这些应用程序,许多浮点单元支持一种非标准的刷新到零模式,在这种模式下,低于正常的编码被视为零。
请注意,有些面向吞吐量的处理器设计具有显著的延迟容忍度,特别是GPU.我对NVIDIA GPU很熟悉,而且我能最好地告诉他们,他们不需要额外的开销就能处理低于正常的操作数,并且在过去的十几年里已经这么做了。据推测,这是以额外的管道阶段为代价的,但是供应商并没有记录这些处理器的许多微体系结构细节,因此很难确定。下面的文章可能会提供一些一般性的见解,不同的硬件设计如何处理低于正常的操作数,有些操作的开销非常小:
E.M. Schwarz,M. Schmookler和S.D. Trong,“具有非正规化数字的FPU实现”。IEEE计算机交易,第54卷,第7号,2005年7月,第825-836页
https://stackoverflow.com/questions/54937154
复制