float の大きな配列を読み取り、それらを使用していくつかの簡単な操作を実行するアプリケーションを作成しています。double よりも高速だと思ったので float を使用していますが、いくつかの調査を行った後、このトピックについて混乱があることがわかりました。誰でもこれについて詳しく説明できますか?
10 に答える
簡単に言えば、「許容できる結果を得るために必要な精度を使用してください」です。
あなたの1つの保証は、浮動小数点データに対して実行される操作が、少なくとも式の最高精度のメンバーで実行されることです。したがって、2 つのfloatの乗算は少なくとも float の精度で行われ、floatとdoubleの乗算は少なくとも倍精度で行われます。標準では、「[floating-point] 操作は、操作の結果の型よりも高い精度で実行される可能性がある」と記載されています。
JIT for .NET が浮動小数点演算を要求された精度のままにしようとしていることを考えると、インテルのドキュメントを参照して演算を高速化することができます。Intel プラットフォームでは、浮動小数点演算は 80 ビットの中間精度で実行され、要求された精度に変換される場合があります。
Intel の C++ Floating-point Operations 1へのガイドから(デッド ツリーしかありません)、彼らは次のように述べています。
- double または long double によって得られる特別な精度が必要でない限り、単精度型 (float など) を使用します。精度の高い型を使用すると、メモリ サイズと帯域幅の要件が増加します。...
- データ型の算術式が混在しないようにする
float および double への/からの不必要なキャストで速度が低下する可能性があるため、最後のポイントは重要です。これにより、x87 が操作の間に 80 ビットの中間形式からキャストするように要求する JIT コードが生成されます。
1. はい、C++ と書かれていますが、C# 標準と CLR の知識により、C++ の情報がこのインスタンスに適用可能であることがわかります。
MCTS試験70-536の「Microsoft.NETFramework-ApplicationDevelopment Foundation 2nd」を読みましたが、4ページ(第1章)にメモがあります。
注組み込み型を
使用したパフォーマンスの最適化ランタイムは32ビット整数型(Int32およびUInt32)のパフォーマンスを最適化するため、これらの型をカウンターやその他の頻繁にアクセスされる整数変数に使用します。浮動小数点演算の場合、これらの演算はハードウェアによって最適化されるため、Doubleが最も効率的なタイプです。
それはトニーノースラップによって書かれました。彼が権威者であるかどうかはわかりませんが、.NET試験の公式本にはある程度の重みがあると思います。もちろん、それは保証ではありません。私はそれをこの議論に加えると思った。
数週間前に同様の質問を紹介しました。要するに、x86 ハードウェアの場合、メモリ バウンドになるか、キャッシュの問題が発生しない限り、float と double のパフォーマンスに大きな違いはありません。その場合、フロートは小さいため、通常は利点があります。
現在の Intel CPU はすべての浮動小数点演算を 80 ビット幅のレジスタで実行するため、実際の計算速度は float と double の間で変化することはありません。
読み込みと保存の操作がボトルネックである場合、float は小さいため高速になります。ロードとストアの間でかなりの数の計算を行っている場合は、ほぼ同じになるはずです。
float と double の間の変換、および両方の型のオペランドを使用する計算を避けることについて、他の誰かが言及しました。これは良いアドバイスです。(たとえば) double を返す数学ライブラリ関数を使用する場合は、すべてを double として保持する方が高速になります。
私はレイ トレーサーを書いていますが、Color クラスの float を double に置き換えると 5% 高速化されます。Vector float を double に置き換えると、さらに 5% 高速になります! かなりクール :)
それはCore i7 920です
387 FPU 演算では、float は、pow、log などの特定の長い反復操作で double よりも高速です (コンパイラが FPU 制御ワードを適切に設定した場合のみ)。
ただし、パックされた SSE 演算を使用すると、大きな違いが生じます。
あなたは間違っている。最近のプロセッサでは、32ビットは16ビットよりもはるかに効率的です...おそらくメモリに関してではありませんが、効果的には32ビットが最適です。
あなたは本当にあなたの教授をもっと「最新の」何かに更新するべきです。;)
とにかく、質問に答えるために; floatとdoubleのパフォーマンスは、少なくとも私のIntel i7 870では(理論上)まったく同じです。
これが私の測定値です:
(1000万回繰り返した後、300回繰り返した「アルゴリズム」を作り、その中から平均をとった。)
double
-----------------------------
1 core = 990 ms
4 cores = 340 ms
6 cores = 282 ms
8 cores = 250 ms
float
-----------------------------
1 core = 992 ms
4 cores = 340 ms
6 cores = 282 ms
8 cores = 250 ms
float か double かに関係なく、プロセッサが最適化されているか、同じであると常に考えていました。集中的な計算 (行列からの大量の取得、2 つの値の比較) の最適化を検索すると、float が約 13% 高速に実行されることがわかりました。
これは私を驚かせましたが、それは私の問題の性質によるものだと思います。演算のコアで float と double の間のキャストは行わず、計算は主に加算、乗算、および減算です。
これは私の i7 920 で、64 ビットのオペレーティング システムを実行しています。
これは、float が double よりもわずかに速いことを示しています: http://www.herongyang.com/cs_b/performance.html
一般に、パフォーマンスを比較するときはいつでも、特殊なケースを考慮する必要があります。たとえば、1 つの型を使用すると追加の変換やデータ マッサージが必要になるかなどです。これらは合計され、このような一般的なベンチマークを裏切る可能性があります。
浮動小数点数は 32 ビット システムで高速になるはずですが、コードをプロファイリングして、最適化が正しいことを確認してください。