質問

私は浮動小数点の大きな配列を読み取り、それらを使用していくつかの単純な操作を実行するアプリケーションを作成しています。double よりも速いと思ったので float を使用していますが、調べた結果、このトピックに関して混乱があることがわかりました。誰かこれについて詳しく説明してもらえますか?

役に立ちましたか?

解決

簡単に言うと、「許容可能な結果を​​得るために必要な精度を使用する」です。

唯一の保証は、浮動小数点データに対して実行される演算が、少なくとも式の最高精度のメンバーで実行されることです。つまり 2 を掛けると 浮くは少なくとも次の精度で実行されます。 浮く, を乗算し、 浮く そして ダブル 少なくとも倍精度で実行されます。この規格では、「[浮動小数点] 演算は、演算の結果の型よりも高い精度で実行できる」と規定されています。

.NET の JIT が浮動小数点演算を要求された精度のままにしようとすることを考えると、演算を高速化するために Intel のドキュメントを参照することができます。Intel プラットフォームでは、浮動小数点演算は 80 ビットの中間精度で実行され、要求された精度まで変換されます。

Intel の C++ 浮動小数点演算ガイドより1 (枯れ木しかないのが残念)、彼らは次のように述べています。

  • double または long double によって得られる特別な精度が必要でない限り、単精度型 (float など) を使用してください。精度の高いタイプでは、メモリ サイズと帯域幅の要件が増加します。...
  • 混合データ型の算術式を避ける

最後の点は重要なので、 float と double の間で不要なキャストを行うと速度が低下する可能性があります。, その結果、x87 に対して操作の間に 80 ビット中間フォーマットからキャストを要求する JIT コードが生成されます。

1.はい、C++ と書かれていますが、C# 標準と CLR の知識により、C++ の情報がこの例に適用できることがわかります。

他のヒント

「Microsoft .NET Framework-Application Development Foundation 2nd」を読みました。 MCTS試験70-536の場合、4ページ(第1章)に注記があります:

  

注組み込みタイプでパフォーマンスを最適化する
  ランタイムは32ビット整数型(Int32およびUInt32)のパフォーマンスを最適化するため、これらの型をカウンターや他の頻繁にアクセスされる整数変数に使用します。浮動小数点演算の場合、これらの演算はハードウェアによって最適化されるため、Doubleが最も効率的な型です。

Tony Northrupによって書かれました。彼が権威者であるかどうかはわかりませんが、.NET試験の公式本にはある程度の重みがあるはずです。もちろん保証ではありません。これをこのディスカッションに追加すると思いました。

数週間前に同様の質問のプロファイルを作成しました。一番下の行は、x86ハードウェアの場合、メモリにバインドされるか、キャッシュの問題が発生しない限り、floatとdoubleのパフォーマンスに大きな違いはありません。その場合、フロートは小さいので一般的に利点があります。

現在のIntel CPUは、すべての浮動小数点演算を80ビット幅のレジスタで実行するため、実際の計算速度はfloatとdoubleの間で変化しません。

ロード&ストア操作がボトルネックである場合、フロートは小さいため、フロートは高速になります。ロードとストアの間でかなりの数の計算を行っている場合、それはほぼ等しいはずです。

フロートとアンプ間の変換を避けることについて他の誰かが言及しました。 double、および両方のタイプのオペランドを使用する計算。これは良いアドバイスです。たとえば、doubleを返す数学ライブラリ関数を使用すると、すべてをdoubleとして保持する方が高速になります。

レイトレーサーを作成しており、Colorクラスのfloatをdoubleに置き換えると、5%の速度が向上します。 Vectorsのfloatをdoubleに置き換えると、さらに5%高速になります!とてもクール:)

これはCore i7 920の場合

387 FPU算術では、pow、logなどの特定の長い反復操作の場合、floatはdoubleよりも高速です(コンパイラがFPU制御ワードを適切に設定する場合のみ)。

パックドSSE算術では、大きな違いが生じます。

Matthijs、

あなたは間違っています。 32ビットは16ビットよりもはるかに効率的です-最新のプロセッサでは...おそらくメモリ単位ではありませんが、効果的には32ビットが効果的です。

実際には、教授をもっと「最新」に更新する必要があります。 ;)

とにかく、質問に答えるために;少なくとも私のインテルi7 870(理論上)では、floatとdoubleのパフォーマンスはまったく同じです。

ここに私の測定値があります:

(「アルゴリズム」を作成し、10,000,000回繰り返した後、それを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

これは、フロートがダブルよりもわずかに速いことを示しています。 http://www.herongyang.com /cs_b/performance.html

一般に、パフォーマンスの比較を行うときは常に、1つのタイプを使用すると追加の変換やデータマッサージが必要になるなど、特別なケースを考慮する必要がありますか?これらは加算され、このような一般的なベンチマークを信じることができます。

32ビットシステムでは浮動小数点演算が高速になりますが、コードをプロファイリングして、正しいことを最適化していることを確認してください。

私は、プロセッサがfloatまたはdoubleに関係なく最適化されているか、同じであると常に考えてきました。集中的な計算(マトリックスからの取得のロット、2つの値の比較)の最適化を検索すると、フロートの実行が約13%速くなることがわかりました。

これは私を驚かせましたが、それは私の問題の性質によると思います。演算のコアでfloatとdoubleの間のキャストを行わず、私の計算は主に加算、乗算、減算です。

これは、64ビットオペレーティングシステムを実行しているi7 920にあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top