これは実際には1つに非常に多くの質問があり、そのうちのいくつかは広すぎます
Cがハードウェアネイティブの80ビットdoubleではなく64ビットdoubleを決定した理由を誰かが説明できますか?
C標準では組み込み型の最小要件のみが義務付けられており、型に使用する形式を選択するのはコンパイラの実装次第であるため、Cとは無関係です。Cコンパイラがカスタムメイドの77ビット浮動小数点型を使用することを妨げるものは何もありません
そして、なぜハードウェアは80ビットのdoubleに落ち着いたのですか?それは調整されていないからです。それぞれのパフォーマンスへの影響は何ですか?
2バイトの倍数に揃えられます。x87は8086+8087にまでさかのぼることを忘れないでください。
これは、操作を正確に丸めるためにより高い精度を必要とする最新のハードウェア実装者とソフトウェア作成者にとっては良いトレードオフですdouble
。タイプが大きすぎると、かなり多くのトランジスタが必要になります。仮数のビット数を2倍にすると、乗数は4倍になる必要があります
x87演算および初期IEEE754標準プロポーザルのプライマリデザイナーであるWilliamKahanは、x87浮動小数点の開発について次のように述べています。 -10進数の内部形式は、Hewlett-Packardの10進数の計算機で機能します。」さらに、Kahanは、64ビットが8087のサイクル時間を増やすことなくキャリー伝播を実行できる最も広い仮数であり、x87拡張精度は将来のプロセッサでより高い精度に拡張できるように設計されていると述べています。 -byte拡張フォーマットは、超高精度演算の価値と、高速で実行するための実装のコストとの間の許容できる妥協点です。まもなく、さらに2バイトの精度が許容できるようになり、最終的には16バイトフォーマットになります...この種の浮動小数点演算のIEEE標準754がフレーム化されたとき、より広い精度に向けた段階的な進化がすでに見られていました。
https://en.wikipedia.org/wiki/Extended_precision#IEEE_754_extended_precision_formats
ご覧のとおり、64ビットの仮数を使用すると、コンポーネント(加算器、乗算器など)を整数ALUと共有できます。
デフォルトの数値タイプに80ビットのdoubleを使用したいと思います。しかし、コンパイラ開発者の選択により、これが最良の選択ではないことが心配になります。x86のdoubleはわずか2バイト短いのに、コンパイラがデフォルトで10バイト長のdoubleを使用しないのはなぜですか?
これは、実際には、カハンの加算などの特別な手法を使用せずに、一時変数(などtmp = (b*c + d)/e
)としてイントラオーバーフローまたはアンダーフローの問題を回避することを目的としています。これはデフォルトの浮動小数点型ではありません。実際、非常に多くの人がorを使用するときに浮動小数点リテラルを誤って使用します。彼らは正しい接尾辞を追加するのを忘れたため、精度が低下し、なぜがとまったく同じであるのかを尋ねられます。要約すると、帯域幅や精度に制限があり、自分が何をしているのかを本当に理解している場合を除いて、ほとんどすべての場合に使用する必要がありますlong double
float
long double
double
double
80ビット長のdoubleとdoubleによって得られる超高精度の例を入手できますか?
完全な値を印刷して、自分で確認することができます。読む価値のある質問もたくさんあります
Microsoftがデフォルトでlongdoubleを無効にするのはなぜですか?
Microsoftはデフォルトでlongdoubleを無効にしません。long double
彼らは、偶然にもと同じフォーマットであるIEEE-754倍精度にマップすることを選択するだけですdouble
。このタイプlong double
は引き続き正常に使用できます。SSEの計算がより速く、より一貫しているので、彼らはそれをしました。そうすれば、以下のような「バグ」を回避できます。
さらに、64ビットのlong doubleには、リソースの浪費である6つのゼロバイトを追加する(または2の累乗以外のタイプの幅を処理する)必要がある奇数サイズがありません。
long double
とはいえ、x86で80ビットが使用できないわけでもありません。現在、MSVCのみが拡張精度型を放棄し、x86の他のコンパイラ(GCC、Clang、ICC ...など)は引き続きそれをサポートし、80ビットIEEE-754をlongdoubleのデフォルト形式にしました。たとえば、GCCには-mlong-double-64/80/128
、-m96/128bit-long-double
の正確な形式を制御する必要があります。long double
または、を変更してABIの互換性を損なう可能性なしに、それをサポートするターゲット のようにGNUC浮動小数点型名long double
を使用できます。Godboltのこの例は、 WindowsまたはLinuxのどちらを対象としているかに関係なく、80ビットのFP計算にコンパイルされます。__float80
規模に関しては、一般的なx86 / x64 PCハードウェアでlongdoubleがどれだけ悪化/遅くなりますか?
レイテンシーとスループットはそれぞれの特定のマイクロアーキテクチャーに依存するため、これに答えることはできません。ただし、多くの浮動小数点演算を実行double
すると、仮数のビット数が少なくなり、SIMDと並列化できるため、大幅に高速になります。たとえば、AVX-512を使用すると、一度に8つのdoubleのベクトルで作業できます。これは、拡張精度タイプでは実行できません。
また、80ビットx87 fpのロードおよびストア命令は、32ビットまたは64ビットとの間で変換する「通常の」バージョンよりも大幅に低速でfstp
あり、使用可能であり、使用可能ではありませんfst
。 最新のCPUでのx87パフォーマンスに関するレトロコンピューティングに関するPeterCordesの回答を参照してください。(実際、これはサイト間の複製であり、MSVCが80ビットx87タイプを公開しない理由を尋ねていlong double
ます。)