9

ショートバージョン

次の行で:

aData[i] = aData[i] + ( aOn * sin( i ) );

aOn0またはの場合1、プロセッサは実際に乗算を実行しますか、それとも条件付きで結果 ( 0for 0、other-value for 1) を計算しますか?

ロングバージョン

アルゴリズムのパフォーマンスの一貫性を調べています。これには、 Branch Predictionの効果を調べることも含まれます。

仮説は、このコードは次のとおりです。

for ( i = 0; i < iNumSamples; i++ )
    aData[i] = aData[i] + ( aOn * sin( i ) );

このコードよりも安定したパフォーマンスを提供します (分岐予測によってパフォーマンスが不安定になる場合があります)。

for ( i = 0; i < iNumSamples; i++ )
{
    if ( aOn )
        aData[i] = aData[i] + sin( i );
}

またはのaOnいずれ01であり、別のスレッドによるループ実行中に切り替えることができます。

実際の条件付き計算 (+ sin( i )上記の例) にはより多くの処理が含まれ、if 条件はループ内にある必要があります (上記の例のような条件は 1 つだけではなく、多数の条件があります。また、への変更は、aOnループごとではなく、すぐに有効になる必要があります。 )。

ifパフォーマンスの一貫性を無視すると、2 つのオプション間のパフォーマンスのトレードオフは、ステートメントの実行にかかる時間と乗算の時間にあります。

1いずれにせよ、プロセッサがやのような値に対して実際の乗算を実行しない場合0、最初のオプションは win-win のソリューション (分岐予測なし、パフォーマンスの向上) になる可能性があることは容易にわかります。

4

1 に答える 1

8

プロセッサは、0s と1s を使用して通常の乗算​​を実行します。

理由は、プロセッサが各計算の前にチェックする場合01条件の導入により多くのサイクルがかかるためです。0および1乗数のパフォーマンスは向上しますが、その他の値のパフォーマンスは低下します (可能性がはるかに高くなります)。

簡単なプログラムでこれを証明できます。

#include <iostream>
#include "cycle.h"
#include "time.h"

void Loop( float aCoefficient )
{
    float iSum = 0.0f;

    clock_t iStart, iEnd;

    iStart = clock();
    for ( int i = 0; i < 100000000; i++ )
    {
        iSum += aCoefficient * rand();
    }
    iEnd = clock();
    printf("Coefficient: %f: %li clock ticks\n", aCoefficient, iEnd - iStart );
}

int main(int argc, const char * argv[])
{
    Loop( 0.0f );
    Loop( 1.0f );
    Loop( 0.25f );

    return 0;
}

出力は次のとおりです。

Coefficient: 0.000000: 1380620 clock ticks
Coefficient: 1.000000: 1375345 clock ticks
Coefficient: 0.250000: 1374483 clock ticks 
于 2013-07-08T22:23:46.943 に答える