2

如果一种语言希望在 x87 硬件和支持 binary128 类型的硬件上提供一致的浮点语义,现有的 binary128 实现是否能够使用要求所有中间结果舍入等效于 80 位类型的规则高效运行在 x87 上找到?尽管 x87 不能有效地使用需要以等效floatdouble精度评估结果的语言,因为这些类型具有不同的指数范围,因此具有非规范化值的不同行为,但似乎 binary128 和 binary80 都使用相同大小的指数字段,因此,四舍五入有效的底部 48 位应该在整个类型的计算范围内产生一致的结果。

语言设计假设未来的 PC 风格硬件将通过 x87 指令或通过可以模拟 80 位类型行为的 FPU 支持 80 位类型,即使值需要 128 位来存储,这是否合理? ?

例如,如果一种语言定义了类型:

  • ieee32 == Binary32 ,除了 real32 或 realLiteral 之外,不能隐式转换为/从任何其他类型转换
  • ieee64 == Binary64 ,除了 real64 或 realLiteral 之外,不能隐式转换为/从任何其他类型
  • real32 == Binary32 急切地转换为 realComp 以进行所有计算,并且可以从所有实数类型隐式转换
  • real64 == Binary64 急切地转换为 realComp 以进行所有计算,并且可以从所有实数类型隐式转换
  • realComp == 中间结果类型,无论存储在其中的精度如何,都需要 128 位来存储
  • realLiteral == 无后缀浮点字面量和常量表达式的类型;在内部作为最大精度值处理,但只能用作文字和常量表达式的类型;存储为最大精度,除非它会立即强制转换为较小的类型,在这种情况下,它将存储为目标类型。

语言是否可以提供承诺始终以 80 位精度处理的语义realComp,或者这样的承诺可能会在某些平台上造成执行时间损失?将其简单地指定为 80 位或更好,并承诺任何有时具有 128 位精度的平台都会始终如一地这样做会更好吗?应该尝试在具有完全 64 位 FPU 的硬件上承诺什么(在没有 64 位 FPU 的典型 16 位或 32 位微控制器上,计算realComp会比 on 更快double)?

4

1 回答 1

1

尽管 x87 不能有效地使用需要以浮点或双精度计算结果的语言,因为这些类型具有不同的指数范围

这是查看情况的一种方法,特别是如果您愿意放弃扩展精度并更改 x87 FPU 控制字以将有效位四舍五入为 53 或 24 位。没有办法告诉 x87 FPU 通过更改控制字来限制指数的范围,因此扩展精度的指数方面最终成为众所周知的问题。您必须通过调节操作数来处理指数,以便扩展精度条件非正规与标准精度无条件非正规匹配。我的这篇博客文章还讨论了未装箱浮点数的实现,这相当于解决了额外的指数宽度问题。

如果您不愿意放弃易于访问的扩展精度,例如通过long double程序可以自由混合的类型floatdouble类型,情况正好相反:指数,如果它们是唯一的问题,您仍然可以按上述方式处理使用一些额外的指令 另一方面,有效数字引入了一个双舍入问题,该问题根本无法廉价处理(*)。

Figueroa 的论文表明,基本的 IEEE 754 操作可以相对容易地模拟两倍的有效数字大小(双舍入是“无害的”)。这是 80(64 位有效位)-> 64(53 位有效位)问题的根源,对于 128(113 位有效位)-> 80(64 位有效位)也是一个问题。

但是由于现在硬件中没有太多实现 128 位四精度,所以这个问题是没有实际意义的。对于我们其他人来说,四精度的硬件实现可以设计为允许完美模拟 80 位双扩展,无论是否更改控制字(并且 binary32 和 binary64 可以相对容易地模拟,即使硬件实现是不合作)。

在 SSE2 中,有针对 binary32 和 binary64 的专用指令,我们中的一些人对这种情况非常满意,因为编译器没有任何借口提供 C99 FLT_EVAL_METHOD=0 语义以外的任何东西(这是我在这篇博文中的结论) . 我们这些为了清晰起见想要像 FLT_EVAL_METHOD=0 这样静态分析程序的人,即使从数值的角度来看,中间结果的扩展精度具有稍微更好的属性。

(*)我应该在这里重复一个评论,我已经在这个答案所指的页面底部发布了一条评论:我很确定有人曾经给我一个参考,参考了对 binary64 基本操作的精确仿真的研究,只有一个x87 配置为 64 位有效位。如果有人知道这可能是哪个文档,我非常想再次查看此参考资料。

于 2014-10-23T13:25:54.417 回答