我有一个小函数,它基于对基于std::vector
实例l,t,d,n
where l,t,d,n
are all计算的参数列表进行元素数学运算来计算参数std::vector<double>
。这是我的程序速度的关键点 - 我已经分析过,我敢肯定。
这是一个使用[]
运算符的工作片段。我在 Core i7、8GB RAM、Windows 7 上使用 Visual C++ 2008 Express 中的 C++ 进行开发,在发布模式下进行了/O2
优化。最终,这将使用 SWIG 编译为 Python 扩展,但我们不要超前。
我还使用 C 数组编写了一个解决方案(见下文)(我以前在 C 中使用的解决方案,但我已经转向 C++ 中的面向对象解决方案,这需要(对于我的应用程序)使用std::vector
s以避免内存泄漏。)
所有三种解决方案都在下面。我在 SO 和其他地方听过很多关于std::vector
迭代器解决方案应该如何(总是??)与数组一样快的讨论,但我的结果表明 100 万次调用需要以下时间:
std::vector
带[]
操作员:2.53 秒std::vector
带迭代器:2.69 秒- C 阵列:0.58 秒
很明显,阵列解决方案要快得多。我对 std::vector 解决方案的编码是否遗漏了一些明显的东西?
编辑
所以看来我的部分问题在于分析。优化优化了我的大部分 c-array 代码,这就是为什么它比任何 std::vector 选项都快得多。我认为我从根本上受到执行所有 exp() 和 pow() 调用的吞吐量的限制。谢谢大家的所有建议,我认为对于我的应用程序,我只是在与处理器速度作斗争。我想 19*6 的 pow 调用大约需要 2 微秒,归根结底并不是那么糟糕。但这对我来说仍然太慢了。 这就是生活...
std::vector<double>
使用带[]
运算符的索引
double phir_power::base(double tau, double delta) throw()
{
double summer=0;
for (unsigned int i=iStart;i<=iEnd;i++)
{
if (l[i]>0)
summer+=n[i]*pow(delta,d[i])*pow(tau,t[i])*exp(-pow(delta,l[i]));
else
summer+=n[i]*pow(delta,d[i])*pow(tau,t[i]);
}
return summer;
}
std::vector<double>
带迭代器
std::vector<double>::const_iterator n_begin=n.begin(), n_end = n.end(), n_iter = n_begin;
std::vector<double>::const_iterator d_begin=d.begin(), d_end = d.end(), d_iter = d_begin;
std::vector<double>::const_iterator t_begin=t.begin(), t_end = t.end(), t_iter = t_begin;
std::vector<double>::const_iterator l_begin=l.begin(), l_end = l.end(), l_iter = l_begin;
for (unsigned int uuu=0;uuu<1e6;uuu+=1)
{
double summer=0;
//Bring the iterators back to the first element
l_iter = l_begin;
d_iter = d_begin;
t_iter = t_begin;
n_iter = n_begin;
for (; l_iter != l_end; ++l_iter,++t_iter,++d_iter,++n_iter)
{
if ((*l_iter)>0)
summer+=(*n_iter)*pow(delta,(*d_iter))*pow(tau,(*t_iter))*exp(-pow(delta,(*l_iter)));
else
summer+=(*n_iter)*pow(delta,(*d_iter))*pow(tau,(*t_iter));
}
rrrrrrrr += summer;
}
t2 = clock();
printf("Time for 1 million calls %g [s] val %g \n",((double)(t2-t1))/CLOCKS_PER_SEC,rrrrrrrr);
C阵列
double r=0;
t0 = clock();
unsigned int qwe;
double ttte = 0;
double term_;
for (unsigned int j=1;j<19;j++)
{
t1=clock();
r=0;
for (unsigned int i=0; i<1e6; i++)
{
term_ = n[j]*pow(delta,d[j])*pow(tau,t[j]);
if (l[j]>0)
term_ *= exp(-pow(delta,l[j]));
r+=term_;
}
ttte+=r/1e6;
t2=clock();
printf("Index %d time %g [s] val %g\n",j,((double)(t2-t1))/CLOCKS_PER_SEC,r/1e6);
}
t3=clock();
printf("Time for 1 million calls %g [s] val is %g\n",((double)(t3-t0))/CLOCKS_PER_SEC,ttte);