10

我注意到编译器在每次使用double算术时都会生成针对 SIMD 寄存器的代码。这适用于未优化和优化的代码。这是否意味着 x87 FP 单元可以被认为是过时的并且只是为了向后兼容而存在?

我还注意到其他“流行”平台也依赖于它们各自的 SIMD 实现,而不是设计为堆栈的 FP。

此外,SIMD 实现往往至少为 128 位宽,所以我想知道这是否意味着操作的(内部)精度高于 x87 FP 单元?

我还想知道性能、吞吐量和延迟,考虑到 SIMD 是在考虑向量执行的情况下构思的,所以我想知道它们如何处理标量。

4

1 回答 1

15

此外,SIMD 实现往往至少为 128 位宽,所以我想知道这是否意味着操作的(内部)精度高于 x87 FP 单元?

SIMD 寄存器的宽度不是它所代表的向量的一个单独分量的宽度。广泛可用的 SIMD 指令集最多提供 IEEE 754 binary64 格式(64 位宽)。这在精度或范围方面不如历史上的 80 位扩展格式。

许多 C 编译器使 80 位格式可用作long double类型。我经常使用它。它适用于大多数中间计算:即使最终结果注定要以 binary64 形式返回,使用它也有助于使最终结果更加准确double。一个例子是这个问题中的函数 ,如果中间计算是用 完成的,那么最终结果的数学直观属性成立long double,但如果中间计算是用与double输入和输出相同的类型完成的,则不成立。

类似地,在为扩展 80 位格式选择参数时必须平衡的许多约束中,一个考虑是通过组合 80 位和来计算binary64 函数是完美的。为了获得最终结果的良好精度,额外的精度是必要的。pow()expl()logl()

但是,我应该注意,当“中间”计算是单个基本操作时,最好不要进行扩展精度。换句话说,当xy属于 类型时double, 的准确度(double)(x * (long double)y)比 的准确度要差很多x * y。这两个表达式几乎总是产生相同的结果,并且在它们不同的极少数情况下,x * y会稍微准确一些。这种现象称为双舍入

于 2014-10-09T14:00:37.183 回答