0

バージョンA:

if ((A)&&(B)) doSth;
if (B) doSthElse;

バージョンB:

if (B)
{
    if (A) doSth;
    doSthElse;
}

パフォーマンスの観点から、これら2つのうちどちらが望ましいですか?

ノート :

  • 実際のコードは1秒間に数百万回使用されるため、パフォーマンスと速度が非常に重要です。プロファイリングに進む前に、何かが足りない場合に備えて、いくつかの情報を教えてください。

  • コードは、Mac OS X10.6.8でClang++-O3を使用して、を使用してコンパイルされています。

4

3 に答える 3

3

Aとは何かに依存しBます。が複雑な関数の場合B、2 番目の関数は 1 回しか評価しませんが、最初の関数は 2 回評価します (Aもちろん成立する場合)。

些細なケース (つまり、両方bool) の場合は問題になりません。

もちろん、プロファイリングすることもできますが、これがボトルネックになるとは思えません。

于 2013-01-21T15:41:42.983 に答える
2

A と B がどちらも単純なブール値であると仮定すると、条件が解決される可能性を考慮する必要があります。

  1. ショートカット評価: (A) が (B) よりも偽に解決される可能性が高い場合は、(A && B) と書き、それ以外の場合は (B && A) と書きます。

  2. 分岐の予測可能性: より予測可能な大きなブロックを囲む条件を使用します。たとえば、B が予測可能な場合、2 番目の形式が優先されます。

  3. 予測不可能な条件付き代入を (? :) に変換してみてください。たとえば、prefer

    x = c ? a : b; // data dependency
    

    if (c) x = a; // control flow dependency
    else   x = b;
    

c が予測できない場合。この場合、制御フローの依存関係を、条件付き移動にコンパイルできるデータの依存関係に置き換えます。コントロールの依存関係が予測できない場合は、正味のゲインです。

于 2013-01-21T16:22:25.103 に答える
0

A値とB値がブール値の場合は、3番目のバージョンをお勧めします。

if (A & B) doSth;
if (B) doSthElse;

このバージョンでは、ビット単位のANDを使用して、複数のブール値から単一の比較を作成します。これは、別の回答で投稿された三項演算子ソリューションにも適用できます。

これは、&&置換ごとにブランチを削除するため、有益な場合があります。 ほとんどの場合、いくつかのブール値を一緒にANDすることは、それぞれの値で分岐を行うよりも安価です。これは、比較的高価な分岐を持つすべてのCPUアーキテクチャに適用されます。これは、アウトオブオーダー実行、または長い命令実行パイプライン(ほとんどすべてを占める)のいずれかです。

重要な注意:x86では、条件付きエグゼキュータと分岐予測子は十分に優れているため、ブールAが十分に予測されている場合(たとえば、変更がほとんどなく、予測率が99.6%を超えている場合)、&&フォームとショートカットを使用する方が実際には効率的です。条件付きの。ただし、ARMおよびPowerPCアーキテクチャは、ほとんどの場合、ブランチの数が少ないというメリットがあります。

于 2013-01-21T21:58:18.903 に答える