【问题标题】: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循环限制的增加而单调增加函数吗
【发布时间】:2016-07-11 14:14:44
【问题描述】:

我想对 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 轴表示迭代的增加限制。

假设:随着限制的增加,时间应该增加。我们 应该有一个严格递增函数

曲线以其他方式显示。为什么循环5300 次和0.00002 秒循环5400 次需要0.00001 秒。正如您在图表中看到的那样,我们有很多次拥有这个东西。

【问题讨论】:

  • 这里有很多错误,我什至不知道从哪里开始。 1)您可能正在编译优化关闭。否则,由于 DCE,它将是一条接近零的平坦线。 2) 有符号整数溢出为 UB。虽然这通常是无害的,但已知一些编译器(即 GCC)会用它做意想不到的事情。 3)您的基准循环太小而没有意义。对于较小的限制,获取时间比运行循环需要更长的时间。
  • 在您正在测量的值上,您应该预计数据中会出现一些噪音。

标签: c++ time benchmarking


【解决方案1】:

假设:

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

随着限制的增加,时间应该增加。我们应该有一个严格递增函数

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

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

【讨论】:

    【解决方案2】:

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

    小波峰和波谷可以用舍入误差来解释。一次您在时钟“滴答”之前调用clock_gettime,而下一次在“滴答”之后立即调用它。这可能会导致第一次看起来短一个“滴答”。这里的“滴答”是时钟的准确性。

    【讨论】:

      猜你喜欢
      • 2022-07-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2020-04-09
      • 2021-10-17
      • 1970-01-01
      • 2012-11-22
      相关资源
      最近更新 更多