web-dev-qa-db-ja.com

C ++での浮動小数点型の使用に関するパフォーマンスおよびその他の問題

C++パフォーマンスプログラミングに興味があるので、私には本当に手がかりがない1つの側面があります。それは、浮動小数点計算と倍精度浮動小数点演算対通常の整数演算を使用することの意味ですか?

これらのタイプの計算でどのようなパフォーマンスの問題を考慮する必要がありますか?使用する演算子の種類を決定するときに考慮すべき他の問題は何ですか?

私が現在知っているのは、倍精度浮動小数点が次に大きく、次に倍精度がおそらく最も高価であることです。整数演算は通常、はるかに単純であるため、CPUで最も高速です。

5
user997112

@ ratchet、@ Sjoerd、@ Stephaneのコメントがあなたの質問に答えます。

質問でのあなたの主張「私が現在知っているのは、ダブルは大きいのでおそらく最も高価であることです」最適化に関するルールを示しています-真-「エキスパートのみ」に続いて「あなたのまだ専門家」.....

基盤となるハードウェアの詳細とコンパイラーがそれらをどのように利用するかを知らない限り、浮動小数点数についての表明はできません。浮動小数点演算は整数演算よりも時間がかかるとは限りません。原則として、プログラマーが浮動小数点コードを正しく作成するのに十分な問題があるため、必要でない限り回避する必要があります。必要に応じて、パフォーマンスはほとんど問題になりません。

経験則として、可能であればintを使用します。FPの操作はめったに遅くなく、多くの場合より高速で予測可能です。FPの操作を使用する必要がある場合、倍精度浮動小数点数を使用します。浮動小数点数には、最も大まかな計算(極端な注意が払われない限り)以外に十分な仮数がなく、丸め誤差が潜む傾向があります。

ただし、すべての経験則と同様に、適切に適用する必要があります。それが重要な場合-それを測定します。

7
mattnz

ジョブに適したツールを使用する

ハンマーしか持っていなかった男のことを昔見たことを覚えていますか?

多くの整数型と多くの浮動小数点型があり、それらの多くの実装があります。これらをよく理解すれば、コードは言うまでもなく、結果がより良くなります。選択するときは、いくつかの基準を使用します。

アプリケーション

アプリケーションが基本的に整数を使用する場合、通常は整数を使用します。 C++では、署名済み(デフォルト)と署名なしの両方があり、署名なしを選択すると、最大制限のほぼ2倍になるだけでなく、コンパイラーが数値の不適切な使用について警告する場合があります。

10進数値を使用する場合は、多くの場合、浮動小数点表現の方が適しています。まず、値が整数に制限されていない場合は、科学、工学、またはビジネスから方程式をプログラムする方が自然な場合があります。 2進化10進数(BCD)は通貨にも役立ちますが、スペースが多く遅くなりますが、適切に使用するといくつかの望ましい特性があります。

アプリケーションが通貨に関連している場合、浮動小数点は正確ではないため、トリッキーなものになる可能性があります。そのため、場合によっては、四捨五入によりセントが増減することがあります。場合によっては、浮動小数点ドルの代わりに整数セントで操作して、速度を上げてより正確にすることができます。

FloatsよりDoublesを優先する

丸め誤差が発生する可能性が低いため、通常、浮動小数点よりも倍精度浮動小数点数を使用します。 C++コンパイラは、基本的な演算子を使用した計算でも、floatを標準ライブラリ関数に渡すときに、floatをdoubleにプロモートすることがよくあります。通常、doubleを使用すると、コードとコンパイラーが生成したマシンコードが少し複雑になります。

非常に頻繁に丸めが問題になる可能性があるため、整数と浮動小数点間の変換、方程式内の評価のシーケンス、ループ内の累積エラー、非常に大きい値と非常に小さい値を一緒に使用した場合の正規化を考慮する必要があります。入力と出力の両方の範囲を検証し、時には中間値を検証して、問題が発生していないことを確認します。

サイズが重要

結果の値が正確であることを保証するために、浮動小数点型の範囲と表現、および少しの数値分析を理解する必要がある場合があります。 http://en.wikipedia.org/wiki/Floating_point には、すばらしい情報がたくさんあります。

倍精度浮動小数点数を支持する浮動小数点数に対する別の反対票として、32ビット浮動小数点数が指数に対して8ビットを消費し、値のスケーリングされたバージョンを保持する仮数部が、符号を考慮した後に23ビットに収まる必要があることを考慮してください。仮数の。 2 ^ 23は特に大きくありません。 100万から1000万まで数えたい場合は、32ビット整数または倍精度浮動小数点数を使用できます。

基盤となるアーキテクチャ

ハードウェア浮動小数点を使用している場合は、通常、それを使用しても問題ありません。そうでない場合でも、高速クロックのフィックスポイントプロセッサ上の高度に最適化されたライブラリは、非常にうまく機能する可能性があります。

8ビットの組み込みの作業馬がある場合は、入力をスケーリングおよび正規化する方法を学び、必ず、固定小数点を使用して反復的で時間のかかる計算を慎重に実装してください。私はArduinoのドキュメンテーションファンですが、組み込みシステムで作業するときは、よりハードウェアを使用するのが好きです。次のリンクは、環境にネイティブの浮動小数点がなく、コンパイラーが浮動小数点のみを提供する(ただし、倍精度浮動小数点数は提供しない)場合の対処法についての良い議論があります。

http://www.sparkfun.com/tutorials/317

多くの固定小数点指向のアーキテクチャ(たとえば、一部のデジタルシグナルプロセッサ(DSP))は、乗算-累算などのハードウェア命令を支援し、整数を使用して乗算または算術シフトを実行するのに役立つ非常に有能な命令を含むことがよくあります。これらを使用するための詳細は、コンパイラーまたはライブラリーによって実行される可能性があるため、特にDSPまたは組み込みプロジェクトで作業する場合は、プロセッサーについてできる限り多くを学ぶことが重要です。

1
DeveloperDon