11

私の質問は非常に基本的なものです。C または C++ の場合:

forループが次のようになっているとしましょう。

for(int i=0; i<someArray[a+b]; i++) {
 ....
 do operations;
}

私の質問は、計算a+bがループごとに実行されるのか、それともforループの開始時に 1 回だけ計算されるのかということです。

私の要件では、値a+bは一定です。a+bが計算され、値someArray[a+b]がループ内で毎回アクセスされる場合、パフォーマンスを向上させるために一時変数を使用しますsomeArray[a+b]

4

12 に答える 12

8

生成されたコードを見るとわかります

g++ -S file.cpp

g++ -O2 -S file.cpp

出力file.sを見て、2 つのバージョンを比較します。すべてのループサイクルで定数値に減らすことができる場合someArray[a+b]、オプティマイザは通常そうし、それを一時変数またはレジスタに引き出します。

于 2013-11-13T14:25:28.983 に答える
5

毎回計算されたかのように動作します。コンパイラが最適化中で、結果が変わらないことを証明できる場合は、計算をループの外に移動することができます。それ以外の場合は、毎回再計算されます。

結果が一定で、速度が重要であると確信している場合は、変数を使用してキャッシュします。

于 2013-11-13T14:25:08.480 に答える
3

forループごとに実行されますか、それともループの最初に1回だけ計算されますか?

コンパイラがこのコードを最適化していない場合は、毎回計算されます。あまりコストがかからない一時変数を使用する方が安全です。

于 2013-11-13T14:23:26.323 に答える
1

計算はforループごとに実行されます。オプティマイザーはスマートで最適化できますが、次のような方がよいでしょう。

// C++ lets you create a const reference; you cannot do it in C, though
const some_array_type &last(someArray[a+b]);
for(int i=0; i<last; i++) {
    ...
}
于 2013-11-13T14:25:38.027 に答える
1

aコンパイラがどれだけ優れているか、使用する最適化レベル、およびとがどのようbに宣言されているかによって異なります。

たとえば、aand/orbvolatile修飾子がある場合、コンパイラは毎回それ/それらを読み取る必要があります。その場合、コンパイラは の値で最適化することを選択できませんa+b。それ以外の場合は、コンパイラによって生成されたコードを見て、コンパイラの動作を理解してください。

これが C でも C++ でもどのように計算されるかについての標準的な動作はありません。

于 2013-11-13T14:28:21.587 に答える
1

とがループ上で変更されない場合a、それは最適化されているに違いありません。bまた、someArray[a+b]触れない場合も最適化されます。フェッチ操作は非常にコストがかかるため、これは実際にはより重要です。

これは、ほとんどの基本的な最適化を備えた中途半端なコンパイラーの場合です。また、常に評価していると言う人は明らかに間違っているとまで言います。常に確実というわけではなく、可能な限り最適化されている可能性が最も高いです。

于 2013-11-13T14:28:35.590 に答える
0

毎回計算される場合もあれば、最適化される場合もあります。外部関数が値を変更できないことをコンパイラが保証できるかどうかは、スコープ内に存在するaかどうかによって異なります。bつまり、それらがグローバル コンテキストにある場合、コンパイラは、ループ内で呼び出す関数がそれらを変更することを保証できません (関数を呼び出さない場合を除きます)。それらがローカル コンテキストのみにある場合、コンパイラはその計算を最適化しようとすることができます。

最適化されたアセンブリ コードと最適化されていないアセンブリ コードの両方を生成するのが、最も簡単なチェック方法です。ただし、その合計のコストは信じられないほど安いので、気にしないのが最善の方法です。最新のプロセッサは非常に高速ですが、遅いのは RAM からキャッシュにデータを取り込むことです。コードを最適化したい場合は、プロファイリングします。推測しないでください。

于 2013-11-13T14:28:51.643 に答える
0

念のため、コンパイルしてアセンブリ コードを確認できます。

しかし、ほとんどのコンパイラは、この種のものを最適化するのに十分賢いと思います。(最適化フラグを使用している場合)

于 2013-11-13T14:26:10.860 に答える