問題タブ [compiler-optimization]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - Visual Studio C++ コンパイラの最適化はコードを壊しますか?
ここで、VS2005 と 2010 の両方で発生している奇妙な問題があります。インライン関数が呼び出される for ループがあります。本質的には次のようなものです (C++、説明目的のみ)。
そして、別の関数のループ:
これで、デバッグ ビルドですべてが正常に動作するようになりました。すべての最適化がオンになっているリリース ビルドでは、これは、逆アセンブルによると、i
なしで直接使用されるようにコンパイルされ* 10
、比較a > 100
は に変わりますがa > 9
、私はそれがa > 10
. a > 9
コンパイラにそれが正しい方法であると思わせる原因について何か手がかりはありますか? 興味深いことに、周囲のコードのマイナーな変更 (たとえば、デバッグの出力) でも、コンパイラはそれを使用i * 10
し、リテラル値の 100 と比較します。
これがやや曖昧であることは承知していますが、古いアイデアに感謝します。
編集:
これは、うまくいけば再現可能なケースです。ここに貼り付けるには大きすぎるとは思わないので、次のようにします。
これを自分のマシンの VS2010 でテストしたところ、問題が発生している元のコードと同じように動作が悪いようです。リリース構成で、IDE のデフォルトの空の C++ プロジェクト テンプレートを使用して、これをコンパイルして実行しました。ご覧のとおり、ブレークはヒットしないはずです (37 * 16 = 592)。i < 4
を削除すると、元のコードと同じように機能することに注意してください。
compiler-optimization - コンパイラ コード生成 -- 条件付きブロック内のレジスタ割り当て
私はコース用のコンパイラを書いています。最適に処理する方法がわからないいくつかの最適化の問題に遭遇しました。レジスタに保持する必要がある (または高速計算のために保持する必要がある) N 個のローカル変数を使用する、入力言語からの while ループがあるとします。レジスタ数 N > K と仮定します。while ループの終わり近くで条件付きレジスタが変更される可能性があります。
たとえば、x のレジスタ (i386 では %eax としましょう) が次のステートメントの前に決定されたとします。
more ステートメント コードでは、x がスタックにスピル バックされる可能性があります。コードが x を再評価するために while ループの先頭に戻ると、%eax を使用しようとしますが、これは x の値を保持していない可能性があります。だから私たちは次のようなものを持つことができます
私が使用している 1 つの解決策は、while ステートメントの前に変更されたすべてのレジスタを強制的にスピルすることです (したがって、レジスタはコード ジェネレーターの観点からは空と見なされます)。while ループのラベルの後、コードは必要に応じてすべてをレジスタにロードする必要があります。
私の解決策は次のようなものです:
私の解決策は少し無関係または不必要であるようです。ここで忘れている一般的な最適化のトリックはありますか?
編集: if や if else などの条件文でも同様のことが発生することにも注意してください。これは、レジスタが条件のブロック内の変数に割り当てられる可能性があるため発生しますが、コード ジェネレーターは、その後の他のすべてのためにレジスタがそこに移動されたと想定します。私はその場合に対処するためのほぼ同じアプローチを持っています。
visual-c++ - VC++ では、/O2 コンパイラ オプション (速度の最適化) に相当する #pragma は何ですか?
msdnによると、
/O2 (最大速度)
と同等です
/Og/Oi/Ot/Oy/Ob2/Gs/GF/Gy
msdnによると、次のプラグマ
#pragma optimize( "[optimization-list]", {on | off} )
/O コンパイラ オプションと同じ文字を "optimization-list" で使用します。プラグマで使用できる文字は次のとおりです。
- g -グローバル最適化を有効にします。
- p -浮動小数点の一貫性を向上させます。
- s または t -マシン コードの短いシーケンスまたは速いシーケンスを指定します。
- y -プログラム スタックでフレーム ポインターを生成します。
/O2 と同じ意味を持つには、どれを使用すればよいですか?
c++ - コンパイラがこれら2つのステートメントを最適化できないのはなぜですか?
Visual C ++で完全な最適化をオンにしても、コンパイラがメインで次の2つのステートメントを最適化できない理由はありますか?メモリ内のint変数にアクセスするための副作用はありますか?
c++ - gcc の最適化によりアプリが失敗する
最適化をオンにしてGCC for ARMを使用すると、本当に奇妙な問題が発生します。最適化を行わずに C++ アプリケーションをコンパイルすると、実行時に期待される結果を出力する実行可能ファイルが生成されます。最適化 (-O1) をオンにするとすぐに、アプリケーションが期待どおりの結果を生成できません。問題を特定するために数日間試しましたが、わかりません。初期化されていない変数をコードから削除し、厳密なエイリアシングが問題を引き起こす可能性がある箇所を修正しましたが、それでも適切な結果が得られませんでした。
私は ARM 用に GCC 4.2.0 を使用しており (プロセッサは ARM926ej-s です)、Montavista Linux ディストリビューションでアプリを実行しています。
以下は、私が使用しているフラグです。
-O1 フラグを取り除き、アプリケーションを再コンパイル/再リンクするとすぐに、適切な出力結果が得られます。フラグからわかるように、最適化を無効にしようとしましたが、問題が発生する可能性があると思いましたが、それでもうまくいきません。
この問題にさらに取り組む方法についての指針はありますか?
ありがとう
c++ - コンパイラによって生成されたクラスのコピー コンストラクタを強制的に *not* コンパイラによってインライン化するにはどうすればよいですか?
別の質問のタイトルは次 のようになります:特定の翻訳単位で、コンパイラによって生成されたコンストラクターのコードをコンパイラーに明示的に生成させるにはどうすればよいですか?
私たちが直面している問題は、1 つのコード パスについて、1 つのオブジェクトの copy-ctor 呼び出しがインライン化されていない場合 (つまり、このコンストラクターが手動で実装されている場合) に、(徹底的に測定された) パフォーマンスが (約 5%) 向上することです。(コードのクリーンアップ中に、このクラスの余分な明示的に実装されたコピー ctor (17 メンバー) が削除されたため、これに気付きました。)
編集:生成されたアセンブリ コードをチェックし、2 つの異なるコード バージョンについて説明したように、インライン化とコード生成が行われていることを確認したことに注意してください。
ここで、手動の copy-ctor コードを元に戻す (コンパイラが生成したものとまったく同じ) か、このクラスの copy-ctor をインライン化しない他の手段を見つけるかの選択に直面しています。
特定の翻訳単位でコンパイラが生成したクラス関数を明示的にインスタンス化する手段 (Microsoft Visual C++ の場合) はありますか? または、それらが使用される各翻訳単位で常にインライン化されますか? (状況をよりよく把握するために、gcc やその他のコンパイラに関するコメントも歓迎します。)
最初の2つの答えは誤解を示しているため、コンパイラによって生成されたクラス関数は、ユーザーによって宣言も定義もされていない場合、コンパイラ自体によってのみ生成されます。したがって、これらの関数はソースコードに存在しないため、修飾子を適用することはできません。
A
デフォルトおよびコピー ctor、dtor、およびコピー演算子があります。これらの関数はコードに存在しないため、一部の declspec を介して変更することはできません。
B
現在、ユーザー提供のコピー ctor があり、ユーザーはそれを実装する必要があります。コンパイラはそのコードを生成しません。
懐疑論者のためのもう少し背景:-) ...
このコードは MS Visual C++ を使用してコンパイルされていますが、組み込み (のような) (リアルタイム) システム用にリンクされています。パフォーマンスは、このシステムでタイミングを取ることによって測定されたので、タイミングを取った人はまともな数値を持っていると思います.
このテストは、2 つのコード バージョンを比較することによって実行されました。唯一の違いは、この 1 つのクラスのインラインと非インライン コピー ctor でした。インライン コードのタイミングは、約 5% 悪化しました。
さらに調べたところ、ある点で私が間違っていたことが明らかになりました。コンパイラは、複雑なコピー コンストラクターに対して個別の関数を生成します。これは独自の裁量で行われ、最適化設定にも依存します。したがって、私たちの場合、コンパイラは特定の状況で間違ったことをしています。これまでの回答から、コンパイラーに別の方法で伝えることができるようには見えません。:-(
c++ - コンパイラはどのようにコードを最適化しますか?
私が別の人の質問に答えていたとき、私はこの質問に出くわしました。コンパイラはどのようにコードを最適化しますか?const、...などのキーワードは役に立ちますか?揮発性物質とインライン関数の事実と、コードをすべて自分で最適化する方法に加えて!
compiler-construction - どのような場合に、アウトオブオーダー実行はより効率的なコードをもたらしますか
私は、メモリバリアがどのように機能するのか、なぜそれが使用されるのか、そしてどのような場合に使用されるべきかを理解しようとしています。ただし、どのような場合に指示の順序を調整する方が効率的かは完全にはわかりません。その例を教えてもらえますか?
c++ - 私のコンパイラは何をしていますか?(memcpyの最適化)
VC ++ 2010の次の設定を使用して、少しコードをコンパイルしています:/ O2 / Ob2 / Oi / Ot
ただし、生成されたアセンブリの一部を理解するのに問題があります。コードにコメントとしていくつかの質問を入れました。
また、現代のCPUで一般的に推奨されるプリフェッチ距離はどれくらいですか?私は自分のCPUでテストすることができますが、より広い範囲のCPUでうまく機能する値を期待していました。たぶん、動的なプリフェッチ距離を使用できますか?
<-編集:
私が驚いたもう1つのことは、コンパイラーがmovdqa命令とmovntdq命令を何らかの形でインターリーブしないことです。これらの命令はある意味で私の理解から非同期であるため。
このコードは、プリフェッチ時に32バイトのキャッシュラインも想定していますが、ハイエンドCPUには64バイトのキャッシュラインがあるように見えるため、プリフェッチのうち2つを削除できる可能性があります。
->
元のコード:
gcc - gcc コンパイラーの最適化の展開
gcc が実際にコードを最適化したコードを見ることに興味があります。私にできる方法はありますか?
私は他のいくつかの同様のクエストを経験しました.いくつかのことを試しました.
- -Wa,ahl=filename.lst :- このオプションは非常に優れています。コードと対応するマシン コードを参照できますが、O3 オプションを有効にするとうまくいきません。
- 最適化されたツリーのダンプ:- gcc が大量のデバッグ情報を提供してくれると確信しています。しかし、私はそれを解読する方法を知りません。誰かが利用可能な情報を指摘できれば幸いです。
gcc が最適化したコードのどの部分を見つけるために、他に良い方法はありますか?
ありがとう、マドゥール