9

短版

在以下行中:

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

如果aOn01,处理器是否实际执行乘法运算,或者它是否有条件地计算出结果(0对于0,其他值1)?

长版

我正在研究算法性能一致性,其中部分涉及到分支预测的效果。

假设是这段代码:

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 );
}

是or ,它可以在另一个线程执行循环期间切换aOn01

实际的条件计算(+ sin( i )在上面的示例中)涉及更多的处理,并且 if 条件必须在循环内(有多种条件,而不仅仅是上面示例中的一个;此外,更改为aOn应该立即生效,而不是每个循环)。

忽略性能一致性,两个选项之间的性能权衡是执行if语句所需的时间和乘法的时间。

无论如何,很容易发现,如果处理器不会对1和之类的值执行实际乘法0,则第一个选项可能是双赢的解决方案(无分支预测,性能更好)。

4

1 回答 1

8

处理器执行与0s 和1s 的常规乘法。

原因是,如果处理器在每次计算之前进行检查01则条件的引入将花费更多的周期。虽然您将获得01乘数的性能,但您将失去任何其他值的性能(这更有可能)。

一个简单的程序可以证明这一点:

#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 回答