使用
gcc 4.6和-O3,我使用简单的时间命令计时以下四个代码
#include
int main(int argc, char* argv[])
{
double val = 1.0;
unsigned int numIterations = 1e7;
for(unsigned int ii = 0;ii < numIterations;++ii) {
val *= 0.999;
}
std::cout<
}
案例1在0.09秒内运行
#include
int main(int argc, char* argv[])
{
double val = 1.0;
unsigned int numIterations = 1e8;
for(unsigned int ii = 0;ii < numIterations;++ii) {
val *= 0.999;
}
std::cout<
}
案例2运行时间为17.6秒
int main(int argc, char* argv[])
{
double val = 1.0;
unsigned int numIterations = 1e8;
for(unsigned int ii = 0;ii < numIterations;++ii) {
val *= 0.999;
}
}
案例3在0.8秒内运行
#include
int main(int argc, char* argv[])
{
double val = 1.0;
unsigned int numIterations = 1e8;
for(unsigned int ii = 0;ii < numIterations;++ii) {
val *= 0.999999;
}
std::cout<
}
案例4在0.8秒内运行
我的问题是为什么第二种情况比其他所有情况都慢得多?案例3显示删除cout使运行时恢复与预期的一致.案例4表明,改变乘数也大大减少了运行时间.在案例2中没有进行哪些优化或优化以及为什么?
更新:
当我最初运行这些测试时,没有单独的变量numIterations,该值在for循环中被硬编码.通常,对此值进行硬编码会使得运行速度比此处给出的情况慢.对于案例3来说尤其如此,它几乎立即使用如上所示的numIterations变量运行,表明James McNellis对于整个循环的优化是正确的.我不确定为什么将1e8硬编码到for循环中会阻止在案例3中删除循环或在其他情况下使事情变慢,但是,案例2的基本前提明显更慢更为真实.
区分装配输出给出了上面给出的情况
案例2和案例1:
movl $100000000,16(%esp)
movl $10000000,16(%esp)
案例2和案例4:
.long -652835029
.long 1072691150
.long -417264663
.long 1072693245