4

I have a "MyFunction" I keep obsessing over if I should or shouldn't use goto on it and in similar (hopefully rare) circumstances. So I'm trying to establish a hard-and-fast habit for this situation. To-do or not-to-do.

int MyFunction()
{   if (likely_condition)
    {
    condition_met:
        // ...
        return result;
    }
    else /*unlikely failure*/
    {   // meet condition
        goto condition_met;
    }
}

I was intending to net the benefits of the failed conditional jump instruction for the likely case. However I don't see how the compiler could know which to streamline for case probability without something like this.

  1. it works right?
  2. are the benefits worth the confusion?
  3. are there better (less verbose, more structured, more expressive) ways to enable this optimization?
4

4 に答える 4

5

あなたがやろうとしている最適化はほとんど時代遅れのようです。最近のほとんどのプロセッサには分岐予測が組み込まれているため、(それが十分に使用されていると仮定して)分岐が行われるかどうかを追跡し、分岐が行われるかどうかの過去のパターンに基づいて分岐が行われる可能性があるかどうかを予測します。 . この場合、速度は主にその予測がどれだけ正確であるかに依存し、予測が実行されるか実行されないかではありません。

そのため、おそらくより単純なコードを使用するのが最適です。

int MyFunction() {   
    if (!likely_condition) {
        meet_condition();
    }
    // ...
    return result;
}
于 2012-10-31T18:22:13.270 に答える
4
  1. condition_met:変数の初期化をスキップしない限り、コードは期待どおりに機能するはずです。

  2. いいえ、難読化されたバージョンがより最適なコードにコンパイルされることさえ知りません。コンパイラの最適化 (およびプロセッサの分岐予測) は、最近非常にスマートになっています。

3.

int MyFunction()
{
    if (!likely_condition)
    {
        // meet condition
    }

    condition_met:
        // ...
    return result;
}

または、コンパイラに役立つ場合(アセンブリを確認してください)

int MyFunction()
{
    if (likely_condition); else
    {
        // meet condition
    }

    condition_met:
        // ...
    return result;
}
于 2012-10-31T18:20:12.423 に答える
4

最新の CPU は、正しい分岐予測を行う場合、どちらの方法でも同等のパフォーマンスで分岐します。したがって、それが内側のループにある場合、のパフォーマンスはif (unlikely) { meet condition } common code;あなたが書いたものと一致します。

また、両方の分岐で共通コードを綴ると、コンパイラは記述したものと同じコードを生成します。共通ケースは句に対して発行され、ifelsejmp共通コードになります。これは、 のような単純な端末ケースで常に見られます*out = whatever; return result;returnデバッグするとき、それらはすべてマージされているため、どれを見ているのかわかりにくい場合があります。

于 2012-10-31T18:21:54.920 に答える
1

以下を使用する代わりに、特定のC ++コンパイラ(ポータブル分岐予測のヒント__builtin_expect()を参照)にマクロ(GCC)などを使用することを強くお勧めします。goto

int MyFunction()
{   if (__builtin_expect(likely_condition))
    {
        // ...
        return result;
    }
    else /*unlikely failure*/
    {   // meet condition
    }
}

他の人も言及gotoしているように、骨からのエラーが発生しやすく悪です。

于 2012-10-31T18:45:26.187 に答える