time - gettimeofday() C++ 不一致

标签 time programming-languages benchmarking stopwatch

我正在做一个涉及比较编程语言的项目。我正在计算阿克曼函数。我测试了 Java、Python 和 Ruby,得到了 10 到 30 毫秒之间的响应。但是 C++ 似乎需要 125 毫秒。这是正常的,还是gettimeofday()的问题? ? Gettimeofday()是在时间.h。

我正在(虚拟)Ubuntu Natty Narwhal 32 位上进行测试。我不缺处理能力(四核 2.13 GHz Intel Xeon)。

我的代码在这里:

#include <iostream>
#include <sys/time.h>
using namespace std;
int a(int m,int n) {
    if (m == 0) {
    return n + 1;
    } else if (m > 0 and n == 0) {
    return a(m-1,1);
    } else if (m > 0 and n > 0) {
    return a(m-1,a(m,n-1));
    }
}

int main() {
    timeval tim;
    gettimeofday(&tim,NULL);
    double t1 = tim.tv_usec;
    int v = a(3,4);           
    gettimeofday(&tim,NULL);
    double t2 = tim.tv_usec;
    cout << v << endl << t2-t1;
    return 0;
}       

最佳答案

假设您正在谈论返回数据的分辨率,the POSIX specificationgettimeofday状态:

The resolution of the system clock is unspecified.


这是因为系统可能具有广泛变化的跟踪小时间段的能力。甚至 ISO 标准 clock()函数包括这样的警告。
如果您谈论调用它需要多长时间,则该标准不保证这些方面的性能。一个实现是完全免费的,在给你时间之前等待 125 分钟,尽管我怀疑这样的实现会在市场上取得多大成功:-)

作为有限分辨率的示例,我输入了以下代码以在我的系统上进行检查:
#include <stdio.h>
#include <sys/time.h>

#define NUMBER 30

int main (void) {
    struct timeval tv[NUMBER];
    int count[NUMBER], i, diff;

    gettimeofday (&tv[0], NULL);

    for (i = 1; i < NUMBER; i++) {
        gettimeofday (&tv[i], NULL);
        count[i] = 1;
        while ((tv[i].tv_sec == tv[i-1].tv_sec) &&
            (tv[i].tv_usec == tv[i-1].tv_usec))
        {
            count[i]++;
            gettimeofday (&tv[i], NULL);
        }
    }

    printf ("%2d: secs = %d, usecs = %6d\n", 0, tv[0].tv_sec, tv[0].tv_usec);
    for (i = 1; i < NUMBER; i++) {
        diff = (tv[i].tv_sec - tv[i-1].tv_sec) * 1000000;
        diff += tv[i].tv_usec - tv[i-1].tv_usec;

        printf ("%2d: secs = %d, usecs = %6d, count = %5d, diff = %d\n",
            i, tv[i].tv_sec, tv[i].tv_usec, count[i], diff);
    }

    return 0;
}
代码基本上记录了底层时间的变化,记录了对gettimeofday()的调用次数。是时候真正改变了。这是在一台相当强大的机器上,所以它的处理能力并不短缺(计数表明它能够为每个时间量调用 gettimeofday() 的频率,大约 5,800 大关,忽略第一个,因为我们不知道什么时候在那里量子我们开始测量)。
输出是:
 0: secs = 1318554836, usecs = 990820
 1: secs = 1318554836, usecs = 991820, count =  5129, diff = 1000
 2: secs = 1318554836, usecs = 992820, count =  5807, diff = 1000
 3: secs = 1318554836, usecs = 993820, count =  5901, diff = 1000
 4: secs = 1318554836, usecs = 994820, count =  5916, diff = 1000
 5: secs = 1318554836, usecs = 995820, count =  5925, diff = 1000
 6: secs = 1318554836, usecs = 996820, count =  5814, diff = 1000
 7: secs = 1318554836, usecs = 997820, count =  5814, diff = 1000
 8: secs = 1318554836, usecs = 998820, count =  5819, diff = 1000
 9: secs = 1318554836, usecs = 999820, count =  5901, diff = 1000
10: secs = 1318554837, usecs =    820, count =  5815, diff = 1000
11: secs = 1318554837, usecs =   1820, count =  5866, diff = 1000
12: secs = 1318554837, usecs =   2820, count =  5849, diff = 1000
13: secs = 1318554837, usecs =   3820, count =  5857, diff = 1000
14: secs = 1318554837, usecs =   4820, count =  5867, diff = 1000
15: secs = 1318554837, usecs =   5820, count =  5852, diff = 1000
16: secs = 1318554837, usecs =   6820, count =  5865, diff = 1000
17: secs = 1318554837, usecs =   7820, count =  5867, diff = 1000
18: secs = 1318554837, usecs =   8820, count =  5885, diff = 1000
19: secs = 1318554837, usecs =   9820, count =  5864, diff = 1000
20: secs = 1318554837, usecs =  10820, count =  5918, diff = 1000
21: secs = 1318554837, usecs =  11820, count =  5869, diff = 1000
22: secs = 1318554837, usecs =  12820, count =  5866, diff = 1000
23: secs = 1318554837, usecs =  13820, count =  5875, diff = 1000
24: secs = 1318554837, usecs =  14820, count =  5925, diff = 1000
25: secs = 1318554837, usecs =  15820, count =  5870, diff = 1000
26: secs = 1318554837, usecs =  16820, count =  5877, diff = 1000
27: secs = 1318554837, usecs =  17820, count =  5868, diff = 1000
28: secs = 1318554837, usecs =  18820, count =  5874, diff = 1000
29: secs = 1318554837, usecs =  19820, count =  5862, diff = 1000
表明分辨率似乎被限制在不超过一千微秒。当然,您的系统可能与此不同,底线是它取决于您的实现和/或环境。

绕过这种限制的一种方法是不做一次,而是做一次 N次,然后将耗时除以 N .
例如,假设您调用您的函数并且计时器说它用了 125 毫秒,您怀疑这似乎有点高。我建议然后在循环中调用它一千次,测量整个一千次所花费的时间。
如果结果是 125 秒,那么,是的,它可能很慢。但是,如果它只需要 27 秒,那将表明您的计时器分辨率是导致看似大时间的原因,因为这相当于每次迭代 27 毫秒,与您从其他结果中看到的相同。
修改您的代码以考虑到这一点将遵循以下原则:
int main() {
    const int count = 1000;
    timeval tim;

    gettimeofday(&tim, NULL);
    double t1 = 1.0e6 * tim.tv_sec + tim.tv_usec;

    int v;
    for (int i = 0; i < count; ++i)
        v = a(3, 4);           

    gettimeofday(&tim, NULL);
    double t2 = 1.0e6 * tim.tv_sec + tim.tv_usec;

    cout << v << '\n' << ((t2 - t1) / count) << '\n';

    return 0;
}

关于time - gettimeofday() C++ 不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7760951/

相关文章:

time - Shopify 时差

javascript - Moment.js 没有使简单的工作时间变得人性化

c - 如何在 FUSE 中创建符号链接(symbolic link)?

math - 什么编程语言可以让我输入一个很长的数字而不将其转换为 float ?

linux - linux 调度程序中上下文切换的基准

performance - 为什么我的 Rust 程序比等效的 Java 程序慢?

java - 增加 Java.sql.date/time 的最佳方法是什么?

java - 如何让函数在调用自身之前等待

c++ - 局部/全局 bool 问题

java - 防止Java 7过早发生GC