我通过在循环中调用成员函数GaussQuadrature
1M次并对整个循环进行计时来对我Quadrature
模板类的一部分进行基准测试(如果你知道更好的方法,请告诉我!) 。在这个类的预期应用程序中,构造函数将被调用一次并且例程将被多次调用,但我尝试在循环内部调用构造函数1M次,而在外部调用它只是为了查看哪个更快。
如果我在循环中调用构造函数,则每次迭代都会调用构造函数,但它看起来像是分配给相同的内存空间(注意下面的代码段,里面有std::cout << "ctor\n";
语句构造函数)。这是巧合还是更深层次?这是片段:
for(int i = 0; i < 1000000; ++i) {
GaussQuadrature<double> Q(N, func, a, b); // some arguments
Q.Quadrature();
std::cout << "address: " << &Q << "\n";
}
这给出了:
ctor
address: 0x7fff23059400
ctor
address: 0x7fff23059400
.
.
.
ctor
address: 0x7fff23059400
在没有循环或构造函数中的print语句的情况下计时,即
clock_t tic = clock();
for(int i = 0; i < 1000000; ++i) {
GaussQuadrature<double> Q(N, func, a, b);
Q.Quadrature();
}
float elapsed = (clock() - (float)tic) / CLOCKS_PER_SEC;
std::cout << std::setprecision(10) << "time: " << elapsed << "\n";
结果
time: 12.47999954
现在,如果我在循环外调用构造函数,那么它当然只调用一次,但实际上需要更长的时间:
clock_t tic = clock();
GaussQuadrature<double> Q(N, func, a, b);
for(int i = 0; i < 1000000; ++i) {
Q.Quadrature();
}
float elapsed = (clock() - (float)tic) / CLOCKS_PER_SEC;
std::cout << std::setprecision(10) << "time: " << elapsed << "\n";
这给出了
time: 12.65999985
我跑了好几次,结果与时间相似。有什么想法吗?谢谢!
答案 0 :(得分:2)
首先,在进行计时测试时,您需要关闭任何文本输出,例如printfs和couts。这很重要,因为通过包含它们,您可以隐藏班级的真实表现。你的测试方法还可以。调用算法100万次是合理的。但请记住缓存记忆。根据内存管理器的行为,可以接收相同的内存指针。最后,我想,在您注释掉文本输出后,您的第二个实现将比第一个更快。
最终建议:您可能更喜欢使用QueryPerformanceFrequency和 QueryPerformanceCounter用于更精确的计时。
答案 1 :(得分:0)
它可能是编译器完成优化的结果。 for循环可以自动“展开”http://en.wikipedia.org/wiki/Loop_unwinding,最大限度地减少分支,这种展开也可以通过CPU和流水线的内部并行性来实现。
“如果循环中的语句彼此独立(即循环中较早出现的语句不会影响它们后面的语句),则语句可能会并行执行。”
尝试禁用所有优化并再次检查这些时间。