【问题标题】:What are the applications/benefits of an 80-bit extended precision data type?80 位扩展精度数据类型的应用/好处是什么?
【发布时间】:2010-10-11 09:09:54
【问题描述】:

是的,我的意思是说 80 位。这不是笔误...

我在浮点变量方面的经验总是涉及 4 字节的倍数,例如单数(32 位)、双数(64 位)和长双数(我见过的称为 96 位或 128 位) )。这就是为什么当我在编写一些代码以读取和写入AIFF (Audio Interchange File Format) files 时遇到80-bit extended precision data type 时有点困惑:选择了一个扩展精度变量来存储音轨的采样率。

当我浏览 Wikipedia 时,我发现上面的链接以及在 IEEE 754-1985 standard 摘要(但不在 IEEE 754-2008 standard 摘要)中的 80 位格式的简要说明。在某些架构上,“扩展”和“长双精度”似乎是同义词。

我还没有遇到过使用扩展精度数据类型的特定应用程序(当然,AIFF 文件采样率除外)。这让我想知道:

  • 是否有人遇到过扩展精度对于某些编程应用程序是必要/有益的情况?
  • 80 位浮点数除了明显的“它比 double 精度高一点,但比 long double 的大多数实现少字节”之外,还有什么好处?
  • 它的适用性正在减弱吗?

【问题讨论】:

    标签: floating-point ieee-754 x87 long-double extended-precision


    【解决方案1】:

    另一个尚未提及的 80 位类型的优势是,在 16 位或 32 位处理器上,它们没有浮点单元,但有一个“乘法”指令,它产生的结果是操作数(16x16->32 或 32x32->64),将 64 位尾数细分为四个或两个 16 位或 32 位寄存器的算术将比跨越相同数量的 53 位尾数的算术更快寄存器,但必须与符号和指数共享 12 个寄存器位。对于不需要比 float 更精确的应用程序,48 位“扩展浮点”类型的计算同样可能比 32 位 float 上的计算更快。

    虽然有些人可能会抱怨扩展精度类型的双舍入行为,但实际上这只是需要完全位精确跨平台再现性的专业应用程序中的问题。从准确性的角度来看,64/128 与 65/128 或 1024/2048ulp 与 1025/2048 的舍入误差之间的差异不是问题;在具有扩展精度变量类型一致的扩展精度语义的语言中,在许多没有浮点硬件的平台(例如嵌入式系统)上使用扩展类型将提供更高的与单精度或双精度浮点类型相比,精度和速度更快。

    【讨论】:

      【解决方案2】:

      对我来说,使用 80 位是必不可少的。这样,当使用 GOTO 库进行矢量内积时,我得到对称矩阵的高阶 (30,000) 特征值和特征向量,还有四个数字,即,对于我在相对论原子中使用的那种矩阵,我使用 13 个有效数字而不是 9 个有效数字计算,这是避免掉入负能量状态的海洋所必需的。我的另一个选择是使用四倍精度算法,它将 CPU 时间增加 60-70 倍,同时也增加了 RAM 需求。任何依赖于大向量内积的计算都会受益。当然,为了将部分内积结果保存在寄存器中,有必要使用汇编语言,就像在 GOTO 库中一样。这就是我爱上我的旧 Opteron 850 处理器的原因,只要它们持续用于我的计算部分,我就会一直使用它。

      80 位速度快,而精度更高却慢得多的原因是 CPU 的标准浮点硬件具有 80 位寄存器。因此,如果您想要额外的 16 位(11 位额外的尾数、4 位额外的指数和 1 位有效未使用的额外位),那么从 64 位扩展到 80 位并不需要太多成本——而扩展就运行时间而言,超过 80 位的成本非常高。因此,如果您愿意,不妨使用 80 位精度。使用它不是免费的,但它相当便宜。

      【讨论】:

      【解决方案3】:

      我使用 80 位进行一些纯数学研究。我不得不对一个变得非常大的无限级数求和,超出了双精度数的范围。收敛性和准确性不是问题,只是处理像 1E1000 这样的大指数的能力。也许一些聪明的代数可以简化一些事情,但是仅仅编写一个具有更高精度的算法比花任何时间思考它更快更容易。

      【讨论】:

        【解决方案4】:

        英特尔的 FPU 在内部使用 80 位格式来获得更高的中间结果精度。

        也就是说,你可能有 32 位或 64 位的变量,但是当它们被加载到 FPU 寄存器中时,它们会被转换为 80 位; FPU 然后(默认情况下)在 80 中执行所有计算,但是;计算完成后,将结果存回 32 位或 64 位变量中。

        顺便说一句 - 一个有点不幸的结果是调试和发布构建可能会产生稍微不同的结果:在发布构建中,优化器可能会在 80 位 FPU 寄存器中保留一个中间变量,而在调试构建中,它将存储在 64 位变量中,导致精度损失。您可以通过使用 80 位变量来避免这种情况,或者使用 FPU 开关(或编译器选项)以 64 位执行所有计算。

        【讨论】:

        • 听起来像是维基百科页面提到的涉及“算术行为的细微差异”的“副作用”之一。 =) 那么,既然 IEEE 754-2008 规范提到了 128 位“四元”格式,我们是否应该期待 80 位 FPU 很快被淘汰?
        • 我不知道标准的发展方向,但我希望英特尔至少会在很长一段时间内保持对 80 位的支持以保持兼容性,即使他们添加了 128 位支持。
        • @gnovice:不太可能; 80 位格式仍然是有效的 IEEE-754 (2008) 类型。具体来说,它是 IEEE-754 标准允许的“binary64 扩展”类型的众多选项之一。也就是说,大多数平台要么使用或正在转向使用 SSE(原生 32 位和 64 位)进行浮点计算,因为它提供了更好的性能。
        • 使用 Borland 编译器时,避免调试和发布版本出现不同行为的简单方法是使用 80 位类型的变量。可惜微软从来不支持他们。
        • @LưuVĩnhPhúc:实际上,鉴于 3d 图形的流行,我希望看到将三个 21、40 或 80 位变量保存到 64、128 或256 数据类型以及(对于较大的类型)一个 8 位或 16 位通用字段。这样可以很好地打包,同时提供比 16、32 或 64 位浮点数更好的精度。
        【解决方案5】:

        Wikipedia explains 80 位格式可以表示整个 64 位整数而不会丢失信息。因此CPU的浮点单元可以用来实现整数的乘除。

        【讨论】:

        • 我明白了,所以一个 80 位 FPU 可以为高达 64 位整数运算提供双重任务。酷。
        猜你喜欢
        • 2012-11-08
        • 2012-11-23
        • 2011-02-27
        • 2016-06-10
        • 2012-11-04
        • 2013-05-23
        • 1970-01-01
        • 2012-05-26
        • 1970-01-01
        相关资源
        最近更新 更多