定点数学比浮点数快吗?

问题描述 投票:4回答:2

多年前,在20世纪90年代早期,我构建了图形软件包,这些图形软件包基于定点算法优化计算,并使用牛顿近似方法对sqrt和log近似的cos,sin和缩放方程进行预先计算。这些先进技术似乎已成为图形和内置数学处理器的一部分。大约5年前,我参加了一个涉及一些旧技术的数值分析课程。我已经编写了近30年的编码,很少见到使用过的旧定点优化,即使在GPGPU应用程序中进行世界级粒子加速器实验之后也是如此。定点方法是否仍然适用于整个软件行业的任何地方,或者这些知识的用处现在已经永远消失了吗?

algorithm graphics numerical-methods
2个回答
6
投票

固定点在不支持任何类型的十进制类型的平台上略微有用;例如,我为PIC16F系列微控制器实现了24位定点类型(更多关于我之后选择定点的原因)。

但是,几乎每个现代CPU都支持微码或硬件级别的浮点,因此不需要固定点。

固定点数限制在它们可以表示的范围内 - 考虑64位(32.32)固定点与64位浮点:64位定点数的小数分辨率为1 /(232),而浮点数的小数分辨率最高为1 /(253);固定点数可以表示高达231的值,而浮点数可以表示高达2223的数字。如果需要更多,大多数现代CPU都支持80位浮点值。

当然,浮点数的最大下降在极端情况下是有限的精度 - 例如在固定点,它将需要更少的位来表示9000000000000000000000000000000.00000000000000000000000000000002。当然,对于浮点数,你可以获得更好的十进制算术平均使用精度,而且我还没有看到一个应用程序,其中十进制算术与上面的例子一样极端,但也没有溢出等效的定点大小。

我为PIC16F实现定点库而不是使用现有浮点库的原因是代码大小,而不是速度:16F88有384字节的可用RAM,总共4095条指令空间。要添加两个预定义宽度的固定点数,我在代码中使用进位输入内联整数(固定点无论如何都不会移动);为了增加两个固定点数,我使用了一个带有扩展32位定点的简单移位和加法函数,即使这不是最快的乘法方法,以便节省更多的代码。

因此,当我只需要一个或两个基本的算术运算时,我就能够在不占用所有程序存储的情况下添加它们。相比之下,该平台上可免费使用的浮点库大约占设备总存储量的60%。相比之下,软件浮点库大多只是几个算术运算的包装器,根据我的经验,它们大多是全有或全无,所以将代码大小减半,因为你只需要一半的函数不起作用好吧

固定点通常不会在速度方面提供太多优势,因为它的表示范围有限:您需要多少位来表示具有15位精度的1.7E +/- 308,与64位双精度相同?如果我的计算是正确的,你需要大约2020位。我敢打赌,那表现不会那么好。

三十年前,当硬件浮点相对较少时,非常特殊用途的定点(甚至是缩放整数)算法可以比基于软件的浮点提供显着的性能提升,但只有在允许的值范围可以是用缩放整数算法有效地表示(原始Doom在没有协处理器时使用这种方法,例如在1992年的486sx-25上 - 在运行频率为4.0GHz的超频超线程Core i7上输入一个超过1000的GeForce卡独立的浮点计算单元,它似乎有点不对劲,虽然我不确定哪个 - 486,或者i7 ......)。

浮点由于其可以表示的值的范围而更通用,并且在CPU和GPU上以硬件实现,它以各种方式击败固定点,除非您确实需要超过80位的浮点精度。花费巨大的定点大小和非常慢的代码。


1
投票

好吧,我编码了20年,我的经验是使用定点有3个主要原因:

  1. 没有FPU可用 固定点一般对DSP,MCU,FPGA和芯片设计仍然有效。此外,没有浮点单元可以在没有定点核心单元的情况下工作,所以所有bigdecimal libs都必须使用固定点...此外,显卡使用固定点很多(标准化设备坐标)。
  2. FPU精度不足 如果你去天文学计算,你很快就会遇到极端情况和处理它们的需要。例如,简单的Newtonian / D'Alembert积分或大气射线追踪在大尺度和低粒度上相当快地击中精密障碍。我通常使用浮点双精度数组来解决这个问题。对于输入/输出范围已知的情况,固定点通常是更好的选择。查看一些击中FPU障碍的示例: Is it possible to make realistic n-body solar system simulation in matter of size and mass? ray and ellipsoid intersection accuracy improvement
  3. 速度 回到过去,由于它使用的界面和api,FPU非常慢(特别是在x86架构上)。为每个FPU指令生成一个中断,更不用说操作数和结果传输过程......因此,CPU ALU中的少数位移操作通常更快。 现在这已不再适用,ALU和FPU速度相当。例如,我在这里测量CPU / FPU操作(在小型Win32 C ++应用程序中): fcpu(0) = 3.194877 GHz // tested on first core of AMD-A8-5500 APU 3.2GHz Win7 x64 bit CPU 32bit integer aritmetics: add = 387.465 MIPS sub = 376.333 MIPS mul = 386.926 MIPS div = 245.571 MIPS mod = 243.869 MIPS FPU 32bit float aritmetics: add = 377.332 MFLOPS sub = 385.444 MFLOPS mul = 383.854 MFLOPS div = 367.520 MFLOPS FPU 64bit double aritmetics: add = 385.038 MFLOPS sub = 261.488 MFLOPS mul = 353.601 MFLOPS div = 309.282 MFLOPS 值随时间变化,但数据类型之间的比较几乎相同。短短几年后,由于数据传输量增加2倍,双打速度变慢。但是还有其他平台的速度差可能仍然有效。
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.