2016-12-07 8 views
1

を初期化コードの下について考える:Cの変数は、オーバーヘッド

int i=0;//initialize here 
for (i=0;i<10;i++) { 
    //... do something here 
} 

私たちに、ループのためにそれを定義したときに、それを初期化する必要がで初期化されませんので、。しかし、初期化すると、バイナリコードに変換した後のオーバーヘッドはありますか?

+5

このような「最適化」は、現代のコンパイラでは決して何の違いもありません。重要な場合は、ターゲットプラットフォームで簡単に確認できます。 –

+0

このようなことが重要であれば、世界のコードは非常に遅くなるでしょう。コンパイラのオプティマイザはこれを処理します。さらに、forループの変数を宣言してください。 – DeiDei

+0

は、コードの最適化の程度によって異なります。最適化が有効になっていれば、最適化されたコンパイラによって最適化されていなければならず、とにかくパフォーマンスに大きな影響を与えるべきではありません。 – Paul

答えて

3

コンパイラは自動変数を動的に割り当てません。話すのには「init」はありません。したがって、スコープの問題を回避する以外に変数宣言を移動させることの背後にある本当の目的はありません。

2

コンパイラは、一般的に、そのような単純なケースの短い作業を行うことができます。最善の方法は、forループ内にint i = 0を入れることです。ループの後にiを使用する必要がある場合は、手前でinitを実行し、forループのinit部分を空のままにします。

+2

私は、コードを読んでいる誰かに、制御変数の初期値が何であるかを見るために他の場所を探すように指示するのは悪いアドバイスだと思います。 –

0

生成するオーバーヘッドを確認するアセンブリ言語。 あなたはgccの-c -O0

経由-S

あなたが-cフラグを使用する必要があります、そして、それはyourcode.sという名前のファイルになりますが、これを行うことができます。

は、最適化のための各コンパイラオプションを指定してgccのコマンドをやり直す前に、各アセンブリ言語.Sファイルの名前を変更し-O1、-O2、-O3。

これらのアセンブリ言語ファイルから、どのオーバーヘッドが存在するのか、それが重要であるかを正確に判断できます。このコード例を考える

int main (int argc, char *argv[]) 
{ 
    int i; 
    int j; 

    i=5543644; /* to have or not to have this line*/ 
    for (i = 0; i < 2342465; i++) 
     j = i; 

    return 0; 
} 

i=5543644が存在し、存在しない場合のために最適化-O0でコンパイルするときに、生成された二アセンブリ言語ファイル内の唯一の違いは、

movl $5543644, -8(%rbp) 
1つのラインであります

をメモリアドレスiにコピーしています。アセンブリ言語で明示的にするためにゼロ以外の値を使用しました。

コンパイラの最適化-O3を使用する場合、結果の2つのアセンブリ言語ファイルはと同じとなります。これにより、最適化によってforループが無用になる直前にi=5543644;がコンパイラに認識され、-のときに見つかったmovl行が生成されないことが判明します。

gcc 4.3.4を使用してこれをテストしました。

だけint i = 0;役に立たないi = 5543644;が直接ループの前にいない場合、コードは、非常に大規模で複雑ななるように、1つは、それがその後、本当の世界のオーバーヘッドがありません知っているために、これを行う必要があるのではなく、あなたの簡単なコード例から、最適化されない可能性があります。その決定を下すには、ソースコードとアセンブリ言語を精査する必要があります。

たとえば、ネストされたforループ内や、OPENMPやその他の並列化ディレクティブ内で、コードに応じて何百万倍もの時間がかかるようなデータ割り当てが行われた場合、オーバーヘッドが発生します。それがどれほど重要なのかはかなり主観的なものかもしれません。

関連する問題