通常、はいです。しかし、保証はなく、コンパイラが行う場所はおそらくまれです。
問題なくほとんどのコンパイラが行うことは、ループから不変な評価を引き出すことです。あなたの条件が
if (a<b) ....
の場合、aとbがループの影響を受けない場合、ループの前に一度比較が行われます。
これは、条件が変化しないとコンパイラが判断できる場合は、テストが安価であり、ジャンプwenllが予測したことを意味します。これは、テスト自体が1サイクルまたは全くサイクルを要しないことを意味する(実際には)。
ループを分割するとどのような場合に有益でしょうか?両方の部分とループ全体が今、コードキャッシュ
に適合しない
a)の1サイクルは、大幅なコスト
bは非常にタイトなループ)、コンパイラはコードのみについての仮定を行うことができます通常、1つのブランチがキャッシュに収まるようにコードを注文することができます。任意のテストせず
、I'dexpectそれは常にNTO良い選択だbecasueこのような最適化は、適用されるa)の場合のみ:ループを分割する場合は悪いだろう
ていますか?
ループを分割してコード・キャッシュを超えてコード・サイズを増やすと、大きなヒットになります。これは、ループ自体が別のループ内で呼び出された場合にのみ影響しますが、コンパイラが通常判別できないものです。
私は
extern volatile int vflag = 0;
int foo(int count)
{
int sum = 0;
int flag = vflag;
for(int i=0; i<count; ++i)
{
if (flag)
sum += i;
else
sum -= i;
}
return sum;
}
VC9は、次のループを分割する(それが実際に有益であるかもしれないいくつかの例1)を得ることができませんでした[編集]
[編集2]
int flag = true;
では、2番目のブランチは最適化されています。 (いいえ、constはここで違いはありません;))
それはどういう意味ですか?
一般的に、私はこれが非常に少数のケースでしか価値がない最適化であることを想起し、実行することができますほとんどのシナリオで簡単に手作業で行うことができます。
お返事ありがとうございます。あなたのウィキペディアのリンクからは、この種の最適化のためのより正確な用語であると思われる "ループの切り換え"のページが見つかりました。 –
これらの用語は実際には切り取られ、乾燥されていませんが、この最適化を記述するためにループホイストとループ不変コード運動は実際には使用されていません。彼らは単一の指示のための多くです。 –
OPによって参照される 'loop unswitching'へのリンク:https://en.wikipedia.org/wiki/Loop_unswitching – BrodieG