[英]Why is the performance of a running program getting better over time?
请考虑以下代码:
#include <iostream>
#include <chrono>
using Time = std::chrono::high_resolution_clock;
using us = std::chrono::microseconds;
int main()
{
volatile int i, k;
const int n = 1000000;
for(k = 0; k < 200; ++k) {
auto begin = Time::now();
for (i = 0; i < n; ++i); // <--
auto end = Time::now();
auto dur = std::chrono::duration_cast<us>(end - begin).count();
std::cout << dur << std::endl;
}
return 0;
}
我反复测量内部for循环的执行时间。 结果如下图所示(y:持续时间,x:重复):
是什么导致循环执行时间减少?
环境: linux(内核4.2)@ Intel i7-2600 ,编译使用: g++ -std=c++11 main.cpp -O0 -o main
编辑1
问题不在于编译器优化或性能基准 。 问题是,为什么性能会随着时间的推移而变得更好。 我试图了解运行时发生的事情。
编辑2
正如Vaughn Cato所提出的,我已将CPU频率扩展策略更改为“ 性能 ”。 现在我得到以下结果:
这证实了Vaughn Cato的猜想。 抱歉这个愚蠢的问题。
您可能看到的是CPU频率缩放(限制)。 当CPU没有被大量使用时,CPU进入低频状态以节省功率。
在运行程序之前,CPU时钟速度可能相当低,因为没有大的负载。 运行程序时,忙循环会增加负载,CPU时钟速度会上升,直到达到最大时钟速度,从而减少时间。
如果您连续多次运行程序,您可能会在第一次运行后看到时间保持在较低值。
在您的原始实验中,变量太多而不会影响测量:
我必须承认,我对你的观察持怀疑态度。 因此,我使用预分配的向量编写了一个小变体,以避免I / O同步效应:
volatile int i, k;
const int n = 1000000, kmax=200,n_avg=30;
std::vector<long> v(kmax,0);
for(k = 0; k < kmax; ++k) {
auto begin = Time::now();
for (i = 0; i < n; ++i); // <-- remain thanks to volatile
auto end = Time::now();
auto dur = std::chrono::duration_cast<us>(end - begin).count();
v[k]=dur;
}
然后我在ideone上运行了几次(考虑到它的使用规模,我们可以假设处理器平均处于不断独立的状态)。 的确,你的观察似乎得到了证实。
我想这可能与分支预测有关, 分支预测应该通过重复模式来改善。
然而,我继续,稍微更新了代码,并添加了一个循环, 重复几次实验 。 然后我开始跑步,你的观察没有得到确认(即最后,时间更长)。 但也可能是在ideone上运行的许多其他进程也以不同的方式影响分支预测。
所以最后,总结任何东西需要一个更谨慎的实验,在运行这个基准测试的机器上(并且只有它)几个小时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.