[解決済み] 最新のハードウェアにおける浮動小数点演算と整数演算の比較
質問
私は C++ でパフォーマンス重視の仕事をしていますが、現在、本来は浮動小数点である問題に対して、"より速いからという理由で整数計算を使用しています。これは、まったく多くの厄介な問題を引き起こし、多くの厄介なコードを追加します。
今、私は、浮動小数点計算がどのように遅いかについて、およそ 386 日頃に読んだことを覚えています、そこでは (IRC)、オプションの共同プロセッサがあったと思います。しかし、確かに、指数関数的に複雑で強力な CPU がある現在、浮動小数点または整数計算を行う場合、速度に違いはないのでしょうか? 特に、実際の計算時間は、パイプラインのストールやメイン メモリからのフェッチなどに比べてごくわずかだからです。
正しい答えは、ターゲットとなるハードウェア上でベンチマークを行うことだと思いますが、これをテストする良い方法は何でしょうか。私は 2 つの小さな C++ プログラムを書き、それらの実行時間を Linux 上の "time" と比較しましたが、実際の実行時間はあまりにも可変です (私が仮想サーバー上で実行しているのは役に立ちません)。何百ものベンチマークを実行し、グラフなどを作成するために丸一日を費やす必要はありませんが、相対的な速度の妥当なテストを得るために何かできることはないでしょうか?何かアイデアや考えはありますか?私は完全に間違っているのでしょうか?
私が使用したプログラムは次のとおりですが、これらは決して同一ではありません。
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <time.h>
int main( int argc, char** argv )
{
int accum = 0;
srand( time( NULL ) );
for( unsigned int i = 0; i < 100000000; ++i )
{
accum += rand( ) % 365;
}
std::cout << accum << std::endl;
return 0;
}
プログラム2
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <time.h>
int main( int argc, char** argv )
{
float accum = 0;
srand( time( NULL ) );
for( unsigned int i = 0; i < 100000000; ++i )
{
accum += (float)( rand( ) % 365 );
}
std::cout << accum << std::endl;
return 0;
}
ありがとうございました。
編集:私が気にしているプラットフォームは、デスクトップ Linux と Windows マシンで動作する通常の x86 または x86-64 です。
編集2(下のコメントから貼り付け)。私たちは現在、広範なコードベースを持っています。本当に私は、「整数計算の方が速いので、float を使用してはならない」という一般論に直面しました - そして、私はこの一般化された仮定を反証する方法 (これが真実である場合) を探しています。私は、すべての作業を行い、その後でそれをプロファイリングすることなしに、私たちのために正確な結果を予測することは不可能であることを理解しています。
とにかく、すべての素晴らしい回答およびヘルプに感謝します。他に何かあれば、遠慮なく追加してください :)。
どのように解決するのですか?
残念ながら、「場合による」としか答えようがありません...。
私の経験では、パフォーマンスには多くの変数があります...特に、整数と浮動小数点演算の間で。 プロセッサーによってパイプラインの長さが異なるため、プロセッサーによって (x86 などの同じファミリーの中でも) 大きく異なります。 また、一部の演算は一般に非常に単純で (たとえば足し算)、プロセッサ内の経路が高速化されていますが、他の演算 (たとえば割り算) には非常に長い時間がかかります。
もう 1 つの大きな変数は、データが存在する場所です。 加算する値がわずかであれば、すべてのデータをキャッシュに格納し、CPU にすばやく送ることができます。 データがすでにキャッシュにある非常に遅い浮動小数点演算は、整数がシステム メモリからコピーされる必要がある整数演算よりも何倍も速くなります。
この質問をされるのは、パフォーマンスが重要なアプリケーションに取り組んでおられるからだと思います。 x86 アーキテクチャ用に開発しており、さらにパフォーマンスが必要な場合は、SSE 拡張機能の使用を検討することをお勧めします。 これは単精度浮動小数点演算を大幅に高速化するもので、同じ演算を複数のデータに対して一度に実行でき、さらにSSE演算のためにレジスタのバンクを別に用意します(※)。 (2 番目の例では、quot;double" の代わりに "float" を使用しているので、単精度の演算を使用していると思われます。).
*注: 古い MMX 命令を使用すると、FPU と同じレジスタを実際に使用するため、FPU と MMX の両方を同時に使用することは不可能であり、プログラムが実際に遅くなります。
関連
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】'cout'は型名ではない
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み] 除算を強制的に浮動小数点にするにはどうしたらいいですか?除算は0に切り捨てられ続けますか?
-
[解決済み] JavaScriptで浮動小数点数の精度を扱うには?
-
[解決済み】浮動小数点値の比較はどのくらい危険か?
-
[解決済み】bashで浮動小数点演算を使用するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】'cout'は型名ではない
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み】システムが指定されたファイルを見つけられませんでした。