使用gcc 4.6和-O3,我使用简单的time命令计时了以下四个代码
#include <iostream>
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<<val<<std::endl;
}
案例1运行时间为0.09秒
#include <iostream>
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<<val<<std::endl;
}
案例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;
}
}
第三个案例运行时间为0.8秒。
#include <iostream>
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<<val<<std::endl;
}
第4个案例运行时间为0.8秒。
我的问题是为什么第二个案例比其他所有案例都要慢得多?案例3表明,去除cout会使运行时间恢复到预期水平。案例4表明,改变乘数也大大降低了运行时间。在第2个案例中没有发生哪些优化或优化?
更新:
当我最初运行这些测试时,没有单独的变量numIterations,该值是硬编码在for循环中的。通常情况下,硬编码此值会使事情比这里给出的情况运行得更慢。对于Case 3来说尤其如此,使用上面显示的numIterations变量几乎立即运行,表明James McNellis正确地指出了整个循环被优化掉了。我不确定为什么将1e8硬编码到for循环中会防止在Case 3中删除循环,或者为什么会使其他案例变慢,但是,第2个案例显著较慢的基本前提是正确的。
比较上述案例的汇编输出结果如下:
案例2和案例1:
movl $100000000, 16(%esp)
movl $10000000, 16(%esp)
案例2和案例4:
.long -652835029
.long 1072691150
.long -417264663
.long 1072693245
int
至少有32位吗? - Oliver Charlesworth