10

double演算が使用されるたびに、コンパイラが SIMD レジスタを対象とするコードを生成することに気付きました。これは、最適化されていないコードと最適化されたコードに適用されます。これは、x87 FP ユニットが廃止され、下位互換性のためにのみ存在すると見なすことができるということですか?

また、他の「人気のある」プラットフォームも、スタックとして設計された FP ではなく、それぞれの SIMD 実装に依存していることに気付きました。

また、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。1 つの例は、この質問の関数です。中間計算が で行われる場合、数学的に直感的なプロパティが最終結果を保持しますが、中間計算が入力および出力とlong double同じ型で行われる場合はそうではありません。double

同様に、拡張 80 ビット形式のパラメーターを選択する際にバランスを取る必要があった多くの制約の中で、考慮すべき点の 1 つは、80 ビットと を合成して binary64 関数を計算するのは完璧だということです。最終結果の精度を高めるには、追加の精度が必要です。pow()expl()logl()

ただし、「中間」の計算が単一の基本演算である場合は、拡張精度を使用しない方がよいことに注意してください。つまり、xyが 型のdouble場合、 の精度は(double)(x * (long double)y)の精度よりわずかに悪くなりますx * y。2 つの式は、ほぼ常に同じ結果を生成し、まれに異なる場合がありますが、x * yわずかに正確です。この現象は二重丸めと呼ばれます。

于 2014-10-09T14:00:37.183 に答える