[解決済み] コンパイラ/最適化ツールで高速なプログラムを作るためのコーディングプラクティス
質問
何年も前、Cコンパイラは特に賢いものではありませんでした。 回避策として K&R が発明したのが レジスタ キーワードを発明し、コンパイラにこの変数を内部レジスタに保持するのは良いアイデアかもしれないと示唆しました。 また、より良いコードを生成するために、三次演算子も作りました。
時が経つにつれて、コンパイラは成熟していきました。 コンパイラは非常に賢くなり、フロー分析によって、レジスタに保持する値について、あなたができることよりも優れた判断を下すことができるようになりました。 レジスタのキーワードは重要ではなくなりました。
FORTRANはある種の操作ではCより速いことがありますが、これは以下の理由によります。 エイリアス の問題のためです。 理論的には、注意深くコーディングすることで、この制限を回避し、オプティマイザーがより高速なコードを生成できるようにすることができます。
コンパイラやオプティマイザがより高速なコードを生成できるようにするために、どのようなコーディング手法がありますか?
- 使用しているプラットフォームとコンパイラーを特定すると、ありがたいです。
- なぜその手法がうまくいくように見えるのでしょうか。
- サンプルコードを推奨します。
以下は 関連質問
[編集]をクリックします。 この質問は、プロファイリング、最適化のための全体的なプロセスに関するものではありません。 プログラムが正しく書かれ、完全な最適化でコンパイルされ、テストされ、実稼働に移されたと仮定してください。 あなたのコードには、オプティマイザが可能な限り最高の仕事をすることを妨げる構成があるかもしれません。 これらの禁止事項を取り除き、オプティマイザーがさらに高速なコードを生成できるようにするために、リファクタリングで何ができるでしょうか?
編集 オフセット関連リンク
どのように解決するのですか?
出力引数ではなく、ローカル変数に書き込む! これはエイリアシングのスローダウンを回避するための大きな助けになります。たとえば、あなたのコードが次のような場合
void DoSomething(const Foo& foo1, const Foo* foo2, int numFoo, Foo& barOut)
{
for (int i=0; i<numFoo, i++)
{
barOut.munge(foo1, foo2[i]);
}
}
の場合、コンパイラはfoo1 != barOutを知らないので、ループのたびにfoo1を再読み込みしなければなりません。また、barOutへの書き込みが終了するまでfoo2[i]を読み込むことができません。制限付きポインターをいじり始めることもできますが、これを実行することは同じくらい効果的です(そしてはるかに明確です)。
void DoSomethingFaster(const Foo& foo1, const Foo* foo2, int numFoo, Foo& barOut)
{
Foo barTemp = barOut;
for (int i=0; i<numFoo, i++)
{
barTemp.munge(foo1, foo2[i]);
}
barOut = barTemp;
}
馬鹿げているように聞こえますが、ローカル変数はどの引数ともメモリ上で重なることはありえないので、コンパイラはよりスマートに処理することができるのです。これは、恐ろしいロードヒットストア (このスレッドで Francis Boivin によって言及された) を回避するのを助けることができます。
関連
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み] noexceptを本当に使うべきはいつですか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】C++プログラムをクラッシュさせる最も簡単な方法は何ですか?
-
[解決済み】固定長 6 int 配列の最速ソート
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] 最後の手段としてのパフォーマンス最適化戦略【終了しました
-
[解決済み] FortranはC言語よりも重い計算を最適化しやすいですか?