web-dev-qa-db-ja.com

C#のfloatよりもdoubleの方が速いですか?

フロートの大きな配列を読み取り、それらを使用していくつかの簡単な操作を実行するアプリケーションを作成しています。ダブルスよりも速いと思ったのでフロートを使用していますが、調査を行った結果、このトピックについて混乱が生じていることがわかりました。誰かがこれについて詳しく説明できますか?

53
Trap

簡単な答えは、「許容できる結果を得るために必要な精度を使用する」です。

1つの保証は、浮動小数点データに対して実行される操作が、少なくとも式の最高精度のメンバーで実行されることです。したがって、2つのfloatの乗算は、少なくともfloatの精度で実行され、floatdoubleの乗算が行われます。 =少なくとも倍精度で実行されます。この標準では、「[浮動小数点]演算は、演算の結果タイプよりも高い精度で実行できる」と規定されています。

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

IntelのガイドからC++浮動小数点演算まで1 (申し訳ありませんが枯れ木しかありません)、彼らは言及します:

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

この最後の点は重要です floatおよびdoubleへの/からの不要なキャストで速度を落とすことができます 、その結果、x87に80ビットの中間フォーマットからキャストするように要求するJITコードが生成されます。操作の合間に!

1。はい、C++と書かれていますが、C#標準とCLRの知識により、C++の情報がこのインスタンスに適用可能であることがわかります。

63
user7116

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

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

それはトニーノースラップによって書かれました。彼が権威者であるかどうかはわかりませんが、.NET試験の公式本にはある程度の重みがあると思います。もちろん、それは保証ではありません。私はそれをこの議論に加えると思った。

20

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

現在のIntelCPUは、80ビット幅のレジスタですべての浮動小数点演算を実行するため、計算の実際の速度は浮動小数点と倍精度の間で変化しないはずです。

19
Dave Tarkowski

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

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

7
Mark Bessey

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

パックされたSSE算術演算では、大きな違いがあります。

4
Dark Shikari

Matthijs、

あなたは間違っている。最近のプロセッサでは、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
3
CReeK

これは、floatがdoubleよりもわずかに速いことを示しています: http://www.herongyang.com/cs_b/performance.html

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

1
torial

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

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

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

1
Tomas Pajonk

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

1
Steven A. Lowe