处理器真的计算零或一的乘积吗?为什么?
Do processors actually calculate multiplication by a zero or one? Why?
短版本
在以下行中:
aData[i] = aData[i] + ( aOn * sin( i ) );
如果aOn
是0
或1
,处理器实际执行乘法,还是有条件地计算结果(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 );
}
其中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 ticksn", 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
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么12.0==11.999999999999999999被认为是真的
- 为什么一个天真的'iter_swap`电位比``swap''慢得多
- 为什么 lambda 会转换为值为真的布尔值?
- 为什么真的陈述是假的
- 为什么我真的只需要一个,却创建了两个对象
- 为什么程序员说"pass by reference"真的很"passing references by value?"为什么这很重要?
- 假和真的定义很奇怪,为什么
- 学习指针C++使用以下代码进入核心转储,我真的不知道为什么?
- 处理器真的计算零或一的乘积吗?为什么?
- 在c++中真的不可能跳过带有默认实参的模板形参吗?为什么语法不这么认为?