2

これはマイクロ最適化ですか、それともまったく最適化ですか?

void Renderer::SetCamera(FLOAT x, FLOAT y, FLOAT z) {
    // Checking for zero before doing addition?
    if (x != 0) camX += x;
    if (y != 0) camY += y;
    if (z != 0) camZ += z;

    // Checking if any of the three variables are not zero, and performing the code below.
    if (x != 0 | y != 0 | z != 0) {
        D3DXMatrixTranslation(&w, camX, camY, camZ);
    }
}

vector.size() を持つ条件で for.. ループを実行すると、アプリケーションは各ループでベクトル内の要素を再カウントすることになりますか?

std::vector<UINT> vect;

INT vectorSize = vect.size();
for (INT Index = 0; Index < vectorSize; Index++) {
// Do vector processing
}

// versus:

std::vector<UINT> vect;

for (INT Index = 0; Index < vect.size(); Index++) {
// Do vector processing
}

私は Visual Studio を使用しています。2 番目の質問については、コンパイラが最適化できるもののように思えますが、それについてはよくわかりません。

4

4 に答える 4

5

vector の実装に応じて、コンパイラはサイズが変更されていないことを理解する場合と理解しない場合があります。結局のところ、ループ内でさまざまなベクトル関数を呼び出すため、いずれもサイズが変わる可能性があります。

vector はテンプレートであるため、コンパイラはそれについてすべてを知っているため、非常にうまく機能する場合、サイズが変わらないことを理解できますが、それはおそらく多すぎる作業です。

多くの場合、次のように書きたいと思うでしょう:

for (size_t i = 0, size = vect.size(); i < size; ++i)
    ...

ここでは、同様のアプローチがイテレータで使用されます。

for (list<int>::iterator i = lst.begin(), end = lst.end(); i != end; ++i)
    ...

編集:最初の部分を見逃しました:

これは最適化ですか?

if (x != 0) camX += x;
if (y != 0) camY += y;
if (z != 0) camZ += z;

いいえ。まず第一に、それらが int だったとしても、値がおそらくほとんどの場合ゼロではない場合のチェックと分岐はより多くの作業になるため、最適化にはなりません。

第二に、さらに重要なことは、フロートであることです。これは、それらを 0 と直接比較してはならないという事実に加えて、基本的に 0 と正確に等しいことはほとんどないことを意味します。したがって、ifs は 99.9999% 真です。

これにも同じことが当てはまります:

if (x != 0 | y != 0 | z != 0)

ただし、この場合、行列の変換にはコストがかかる可能性があるため、次のようにすることができます。

#define EPS 1e-6 /* epsilon */
if (x > EPS || x < -EPS || y > EPS || y < -EPS || z > EPS || z < -EPS)

はい、行列の乗算と比較すると、これはおそらく最適化です。

また、たとえば最初から真で||ある場合に短絡するものを使用したことにも注意してください(残りは計算されません)が、それは起こりません。x > EPS|

于 2013-04-29T16:54:32.753 に答える
2

多くのアーキテクチャでは、最初の 3 行は非最適化であると思われます。これは、浮動小数点比較を導入してから分岐する可能性があり、常に加算を行うよりも遅くなる可能性があるためです (浮動小数点であっても)。

一方、変換を行う前に、少なくとも 1 つのコンポーネントが非ゼロであることを確認することは適切に思えます。

2番目のケースでは、一定の時間である必要があり、ほぼ確実にのサイズsizeに直接アクセスできるようにインライン化されます。vectorほとんどの場合、完全に最適化可能です。そうは言っても、サイズをオフに保存することでコード/ループを読みやすくすることができる場合があります。これは、ループ中にサイズが変更されないことを明確に示しているためです。

于 2013-04-29T16:54:18.847 に答える
2

まず、については、この SO の質問vector.size()を参照 してください。ちなみに、 O(1)ではない実装は見たことがありません。std::vector::size()

if (x != 0) camX += x;ただし、これcmpとその結果jneは、単に変数を追加するよりも遅くなりますx編集:50%をはるかに超えるキャッシュミスが予想される場合を除きますcamX

于 2013-04-29T16:55:10.013 に答える