繁体   English   中英

为什么运行程序的性能会随着时间的推移而变得更好?

[英]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时钟速度会上升,直到达到最大时钟速度,从而减少时间。

如果您连续多次运行程序,您可能会在第一次运行后看到时间保持在较低值。

在您的原始实验中,变量太多而不会影响测量:

  • 其他活动进程使用您的处理器(即安排您的操作系统)
  • 你的循环是否被优化的问题
  • 访问和缓冲到控制台。
  • CPU的初始模式(请参阅有关throtling的答案)

我必须承认,我对你的观察持怀疑态度。 因此,我使用预分配的向量编写了一个小变体,以避免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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM