Izh*_*aki 7 c c++ algorithm performance processors
在以下行中:
aData[i] = aData[i] + ( aOn * sin( i ) );
Run Code Online (Sandbox Code Playgroud)
如果aOn
是0
或者1
,处理器是否实际执行乘法,或者它是否有条件地计算出结果(0
for 0
,other-value for 1
)?
我正在研究算法性能的一致性,这部分涉及到分支预测的影响.
假设是这段代码:
for ( i = 0; i < iNumSamples; i++ )
aData[i] = aData[i] + ( aOn * sin( i ) );
Run Code Online (Sandbox Code Playgroud)
将提供比此代码更稳定的性能(分支预测可能会破坏性能):
for ( i = 0; i < iNumSamples; i++ )
{
if ( aOn )
aData[i] = aData[i] + sin( i );
}
Run Code Online (Sandbox Code Playgroud)
与aOn
是0
或1
,它可以在循环执行期间由另一个线程切换.
实际的条件计算(+ sin( i )
在上面的例子中)涉及更多的处理,if条件必须在循环内(有很多条件,不仅仅是上面例子中的一个条件;同样,更改aOn
应立即生效而不是每个循环).
忽略性能一致性,两个选项之间的性能权衡是在执行if
语句和乘法的时间.
无论如何,很容易发现,如果处理器不能执行像1
和等值的实际乘法0
,则第一个选项可能是双赢解决方案(没有分支预测,性能更好).
处理器使用0
s和1
s 执行常规乘法.
原因是,如果处理器在每次计算之前0
和1
之前检查,那么条件的引入将需要更多的周期.虽然你会获得性能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;
}
Run Code Online (Sandbox Code Playgroud)
输出为:
Coefficient: 0.000000: 1380620 clock ticks
Coefficient: 1.000000: 1375345 clock ticks
Coefficient: 0.250000: 1374483 clock ticks
Run Code Online (Sandbox Code Playgroud)