基准测试(for循环的执行时间):随着for循环极限的增加,我们不应该有一个单调递增的函数吗?

Benchmarking (execution time of a for loop): shouldn't we have an monotonic increasing function with the increase of the limit of the for loop

我想对 for 循环进行基准测试。我决定将 for 循环中的变量增加 100 并相应地测量时间。

#include <cstdio>
#include <ctime>
#include <time.h>
#include <iostream>
#include <random>
#include <iomanip>      // std::setprecision
using namespace std;

double difference(timespec start, timespec end);

int main()
{
    timespec time1, time2;

    for(int limit = 0; x < 100000; limit+= 100)
    {
      clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
      int temp = 0;
      for (int i = 0; i< limit; i++)
        temp+=temp;

      clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
      std::cout << std::fixed;
      std::cout << std::setprecision(5);
      cout<<x <<" " << difference(time1,time2)<<endl;
    }

    return 0;
}

double difference(timespec start, timespec end)
{
    timespec temp;
    if ((end.tv_nsec-start.tv_nsec)<0) {
        temp.tv_sec = end.tv_sec-start.tv_sec-1;
        temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
    } else {
        temp.tv_sec = end.tv_sec-start.tv_sec;
        temp.tv_nsec = end.tv_nsec-start.tv_nsec;
    }
    return (temp.tv_sec + temp.tv_nsec) / 1000000000.00;
}

图表

y 轴表示以秒为单位的时间,x 轴表示迭代的增加限制。

Hypothesis: With the increasing limit the time should increase. We should have a Strictly Increasing Function

曲线显示为其他。为什么循环 5300 次需要 0.00001 秒,循环 5400 次需要 0.00002 秒。正如您在图表中看到的那样,我们有很多次遇到这种情况。

您可以清楚地看到曲线中的台阶,这意味着您在测量中遇到了精度障碍。换句话说,clock_gettime 调用无法为您提供任何更准确的值,并且多次迭代测量的是相同的时间值,因为运行之间没有足够大的差异。

小峰和小谷可以用舍入误差来解释。有一次你在时钟 'tick' 之前调用了 clock_gettime,而下一次是在 'tick' 之后调用了它。这可能会导致第一次看起来短一个'tick'。这里的'tick'是时钟的精度。

Hypothesis:

假设是对现象的解释。由于您是在实际观察任何现象之前提出这一点,因此它不能成为假设。此外,如果如您所说,它直接与观察结果相矛盾,则不能作为对它们的解释,因此不是假设。

With the increasing limit the time should increase. We should have a Strictly Increasing Function

据我所知,观察结果与此并不矛盾。

曲线中的伪影很容易用时钟的有限分辨率来解释:它显然无法测量小于 1e-5 的时间差;小于 1e-5 的变化将显示为扁平线或离散的 1e-5 变化。