3

私はこれらの2つの機能を持っています:

template<int N>
void fun()
{
    for(int i = 0; i < N; ++i)
    {
        std::cout<<i<<" ";
    }
}

void gun(int N)
{
    for(int i = 0; i < N; ++i)
    {
        std::cout<<i<<" ";
    }
}

最初のバージョンでは、コンパイラは小さな N ごとにループを最適化すると仮定してもよろしいですか (小さな N = {1, 2, 3, 4} を意味します)

4

5 に答える 5

3

最初のバージョンでは、コンパイラーは小さな N ごとにループを最適化すると仮定してもよろしいですか?

「想定」という言葉は強い言葉ですが、これは典型的な最適化です。最適化が不可欠である場合、潜在的な最適化に最終的に失望することになります。

コンパイラが関数をインライン化できる場合、 2 番目のバージョンでも同じ最適化が行われる可能性があります。

于 2013-03-29T14:03:49.290 に答える
2

最適化が何を行うかについての保証はありませんが、適切な最適化レベルが与えられれば、通常、手動で最適化する場合よりも優れた選択を行うことに依存できます。

生成されたコードを本当に知りたい場合は、結果のアセンブリをいつでも確認できます。

于 2013-03-29T14:06:43.613 に答える
1

最適化レベルとフラグによって異なります。-O0 -g(最適化なし、デバッグを有効にする)、-O3(速度を積極的に最適化する)、および(スペースを最適化する)の間には大きな違いがあり-Osます。

最近では、速度を最適化する場合でも、ループのアンローリングが必ずしも成功するとは限りません。コードが多すぎると、命令キャッシュ ミスが発生する可能性があり、単純なループをインライン化することによる高速化を大幅に上回ります。そして、このようなループ内の条件付き分岐のコストは、分岐予測が最後の反復以外のすべてを正しく予測するため、ほとんど無視できます。

于 2013-03-29T14:06:59.287 に答える
1

コンパイラが関数のいずれかをインライン化できる場合、それが正しいと判断した場合は、ループも展開します。コンパイラがループを展開する利点があると判断するタイミングと方法は非常に複雑な問題であり、使用可能なレジスタの数、ループ内で何が起こるかなど、他の要因に大きく依存します (たとえば、上記の例は疑わしいです)。 、cout ...おそらく数千倍の時間を消費することを考えると、ループに含まれる5つほどの命令を減らすことで多くの時間を得ることができます-コンパイラがそれを理解できるかどうかは別の問題ですが、完全に不明というわけではありませんコンパイラが関数が小さいかどうかをある程度理解できるようにします。

一方、コードが次のようになっているとします。

int arr[N];  // Global array. 

template<int N>
int fun()
{
    int sum = 0;
    for(int i = 0; i < N; ++i)
    {
        sum += arr[i];
    }
}

次に、コンパイラがループを展開して次のようになることを期待します。

    int *tmp = arr;
    sum += *tmp++;
    sum += *tmp++;
    sum += *tmp++;
    sum += *tmp++;
    sum += *tmp++;

N = 5 と仮定します。

そしてこれは、コンパイラに「可視」であり、コンパイル時に N が既知であるすべての関数に適用されます。したがって、別のソース ファイルにないと仮定すると、 (テンプレート関数であるため、このコンパイル ユニットで表示される必要がある)gunとまったく同じようにインライン化および展開されると予想されます。fun

于 2013-03-29T14:13:08.500 に答える
0

もう少し明確にしたい場合は、スイッチ ケース フォールスルーを使用してループを展開するDuff's Deviceを使用できます。ただし、実際にどれだけうまく機能するかは言えません。ただし、代わりにそれをアンロールするようにコンパイラーにヒントを与えることができれば、その方が高速になると思います。

コンパイラも非常に賢く、絶対確実というわけではありませんが、コンパイラの最適化の選択は一般的に私たち自身の直感よりも優れています。

于 2013-03-29T14:13:15.447 に答える