5

詳細については、x87PCアーキテクチャとCコンパイラについて話しています。

私は自分のインタプリタを書いていますが、doubleデータ型の背後にある理由が私を混乱させます。特に効率が懸念される場合。doubleCがハードウェアネイティブの80ビットではなく64ビットを決定した理由を誰かが説明できますdoubleか?そして、なぜハードウェアは80ビットdoubleに落ち着いたのですか?それは調整されていないからです。それぞれのパフォーマンスへの影響は何ですか?デフォルトの数値タイプに80ビットを使用したいと思います。doubleしかし、コンパイラ開発者の選択により、これが最良の選択ではないことが心配になります。

  1. doublelong doublex86ではわずか2バイト短いのに、コンパイラがデフォルトで10バイトを使用しないのはなぜですか?
  2. 80ビットlong doublevsで得られる超高精度の例を入手できますdoubleか?
  3. long double Microsoftがデフォルトで無効にするのはなぜですか?
  4. long double規模に関しては、一般的なx86 / x64 PCハードウェアでどれほど悪い/遅いですか?
4

3 に答える 3

3

Mysticialによると、その答えは、Microsoftがデータ型にSSE2を使用しているということです。double浮動小数点ユニット(FPU)x87は、最新のCPU拡張機能と比較して、時代遅れで低速であると見なされています。SSE2は80ビットをサポートしていないため、コンパイラは64ビット精度を選択します。

32ビットx86アーキテクチャでは、すべてのCPUにまだSSE2が搭載されていないため、コンパイラスイッチ/arch:SSE2が指定されていない限り、Microsoftは浮動小数点ユニット(FPU)x87を使用します。コードを古いものと互換性がないのはどれですか?CPU。

于 2012-04-21T04:16:57.237 に答える
2

間違った質問。これはCとは関係ありません。すべての言語で、32ビットの標準浮動小数点単精度と64ビットの倍精度としてAFAIKが使用されます。異なるハードウェアをサポートする言語としてのCは、

sizeof(float)<= sizeof(double)<= sizeof(long double)

したがって、特定のCコンパイラがすべてのデータ型に32ビットfloatを使用することは完全に許容されます。

Intelは、Kahansが可能な限り高い精度をサポートし、精度の低い形式(32ビットおよび64ビット)での計算は80ビットの精度で内部的に実行する必要があるとアドバイスすることを決定しました。

精度と指数範囲の違い:64ビットは約。10進数の16桁と最大指数308、80ビットの最大指数は19桁と4932です。

はるかに正確で指数範囲がはるかに広いため、オーバーフローやアンダーフローなしで中間結果を計算でき、結果の丸め誤差が少なくなります。

したがって、問題は、longdoubleが80ビットをサポートしない理由です。実際、多くのコンパイラそれをサポートしていましたが、使用の欠如とベンチマークパフォーマンスの実行はそれを効果的に殺しました。

于 2012-04-24T13:54:02.260 に答える
2

これは実際には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 doublefloatlong doubledoubledouble


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ます。)

于 2013-08-08T00:33:06.157 に答える