我的代码如下:优化元件的总和在阵列
double a,b; //These variable are inputs to the function
double *inArr; //This is also an iput to the function whose size is NumElements
double *arr = new double[numElements]; //NumElements is ~ 10^6
double sum = 0.0;
for(unsigned int i=0;i<numElements;++i)
{
double k = a*inArr[i] + b; //This doesn't take any time
double el = arr[i]; //This doesn't take any time
el *= k; //This doesn't take any time
sum += el; //This takes a long time!!!
}
此代码越过每个时间计算的值k,对于每个元件它增加了k次该元素来总结数组的元素。我将代码分成了很多步骤,以便当我的分析器告诉我哪一行需要很长时间时,我将确切知道哪个计算是罪魁祸首。我的配置文件告诉我,将el加总是什么会减慢我的程序速度(这看起来有点奇怪,简单的加法会很慢,但我称这个函数为数百次,每次执行数百万次计算)。我唯一的理论是,因为总和在不同的范围,使用它的操作需要更长的时间。所以我编辑的代码是:
double a,b; //These variable are inputs to the function
double *inArr; //This is also an iput to the function whose size is NumElements
double *arr = new double[numElements]; //NumElements is ~ 10^6
double sum = 0.0;
for(unsigned int i=0;i<numElements;++i)
{
double k = a*inArr[i] + b; //This doesn't take any time
double el = arr[i]; //This doesn't take any time
el *= k; //This doesn't take any time
double temp = sum + el; //This doesn't take any time
sum = el; //This takes a long time!!!
}
现在sum操作花费很少的时间,即使它访问sum变量。这项任务现在需要很长时间。我的理论是否正确,发生这种情况的原因是分配给不在当前范围内的变量需要更长的时间?如果是这样,为什么这是真的?有什么办法可以快速完成这项任务吗?我知道我可以使用并行化来优化这个,我想知道我是否可以顺序地做得更好。我使用VS 2012以发行模式运行,我使用VS性能分析器作为分析器。
编辑:
一旦我删除了原来的访问inArr是什么是最耗时的优化。
你为什么不使用'std :: accumulate(std :: begin(arr),std :: end(arr),0.0,[](auto sum,auto elem){return sum + elem * someQuickCaclc();});'?这应该会给你高度优化的代码。 – TemplateRex
您是否尝试禁用优化(/ O1,/ O2)标志?这可以模仿一些分析。 –
*您认为每条迭代所需的时间*“很长时间”*多长时间?飞秒?小时?天? – Roddy