プロが教えるわが家の防犯対策術!

コンパイルの「デバッグフラグ」と「最適化フラグ」の違いによる実効時間の差がなぜ生じるのか、という課題がポンッとだされたんですが、はっきり言って解りません。
完全な回答でなくてもいいので、どなたか、アドバイスください。

A 回答 (3件)

gcc(GNU C compiler)についてです。



 私も気になったので簡単なプログラム(vector型に1~10000を順にpush
してclearする、というのを10000回繰り返す)をつくって試してみました。

 これを、「1.コンパイルオプション無し」「2.デバッグオプション有り」
「3.最適化オプション有り」「4.最適化オプション有り+デバッグ
オプション有り」の4条件について、各20回ずつ実行し、得られた各20個の
実行時間データをt検定に掛けました。

 まず、デバッグオプションについてですが、1、2、の間で実行時間に
有意な差は認められず、3、4、の間でも優位な差は認められませんでした。

 この結果からは、gccにおいてはデバッグオプションを付けたからといって
実行時間が長くなるとは言えない、と言えます。

 gccではデバッグオプションを付けた際に、余分なライブラリを
リンクするのではなく、ソース内で指定された変数名などのシンボルを
オブジェクトファイルに埋め込むだけであるため、実行時間に
有意な差は生じないのだと思います。(シンボルの分だけ実行ファイルの
サイズは飛躍的に大きくなるので、少しは遅くなるのでしょうが、
上記のような小規模のプログラムでさえ、その影響は無視できるものの
ようです)

 しかし、上記の条件4.はgcc固有の、かなり特殊なもののようです。
すなわち、他のコンパイラではデバッグフラッグと最適化フラッグは
同時には指定できない、というのが一般的なようです。

 その理由はalfeimさんのサンプルプログラムで明らかなように、
最適化をすると、ソースコード上での実行の流れと実際の実行の流れが
変わってしまう為です。

 したがって、a-kumaさんが仰るような、デバッグオプションを付けると
最適化ができないので遅くなるというのは、gccにおいては成り立たないよう
に思いますが、かなり一般的な現象なのではないかと思います。

 もう一点、最適化オプションをつけると速くなるというのは自明ですね。
上記の1は3の、2は4のそれぞれ6倍の実行時間が掛かりました。
その理由としては、マシンの特性や、コンパイルの対象となる高級言語の
コマンドが実行される文脈、などに依存した最適化が行なわれるためである、
ということになるんでしょうか。どのような最適化が行なわれるかは、
コンパイラやマシンに依るようです。

 alfeimさんの例ですとか、実行回数がコンパイル時に分るような
ループを展開するとか、変数をできるだけレジスタに割り当てるとか、
関数の再帰呼出しの最後の数回を展開するとか、
gccのマニュアルを見ただけでも色々あるみたいですね。
    • good
    • 0

デバッグフラグ:


VisualC++では「標準では」最適化無効ですが、設定を変えれば最適化オプションをつけてデバッグ情報を付加できます。(でないとRelease版でのみ出るようなバグに対処できなくなりますから)
デバッグフラグをつけてコンパイルした場合、対応ソースコードの対応行の指定や変数情報が付加され、VisualC++では確保した変数の自動初期化(コンパイルオプションによってはデバッグフラグを切っていても自動初期化する事は出来ますが・・・)やメモリ確保/開放関数の差し替え等があります。
デバッグのサポートをする命令が通常コンパイル時の命令群に付与されますので、実行速度は遅くなります。

最適化:
 たとえば以下のようなソースコード

for(int i = 0; i < 10; i++)
{
int a;
/* 適当な処理 */
}
のようなものがあった場合、ブロック内のint a;の宣言はデータ操作の副作用が無いので、ループ外で宣言しても実質変わりがありません。しかしマシン語レベルで比較すると、ループ内で変数確保をした場合、多くのCコンパイラではスタック操作の命令が実行されますので、最終的な結果を見る場合、ループ外で変数宣言をした方が、実行効率は良くなります。このような実行上、不都合はないが速度向上の邪魔になるものや、コードサイズの面で無駄なコードをシェイプしてくれるのが最適化です。
最適化にもいろいろあり、上記の例のような速度最適化やコードサイズの最適化等があります。
実際にどうなっているか等はコンパイラについての本やコンパイラのソースコードなどを読まれると良いかと思います。
    • good
    • 0

まず「最適化フラグ」から。



「最適化」は、分かりますか?
ソースで書かれていることを、機械語に翻訳するときに、(何かが)最適になる
ようにコンパイラが気を利かせてくれること、です。その「何か」には、実行速度
もありますので、最適化を指定する/しないで、実行速度(実行時間)が変わって
くるのは、当たり前ですね。

次に「デバッグフラグ」について。

デバッグフラグ、というあたりで、Visual C++ っぽいんですが、ふつう、デバッグ
のプロジェクトだと、最適化をしないようになります。つまり、最適化をしないから
遅くなる。

また、デバッグを指定したときには、デバッグ用のライブラリがリンクされるので
すが、こいつらは、デバッグのために有効な情報を内部で抱えたりなど、普通の
ライブラリに比べて、やってくれることが少し増えてます。

その処理が少し増えたことによって、処理速度が遅くなる、ということです。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!