c - 如何测量 cpu 时间和挂钟时间?

标签 c performance time cpu

我看到很多关于这个的话题,甚至在 stackoverflow 上,例如:

How can I measure CPU time and wall clock time on both Linux/Windows?

我想同时测量 cpu 和 wall time。虽然在我发布的主题中回答问题的人建议使用 gettimeofday 来测量挂钟时间,但我读到最好使用 clock_gettime。所以,我写了下面的代码(可以吗,它真的测量墙上时间,而不是 cpu 时间吗?我在问,因为我找到了一个网页:http://nadeausoftware.com/articles/2012/03/c_c_tip_how_measure_cpu_time_benchmarking#clockgettme 上面说 clock_gettime 测量一个cpu time...) 真相是什么?我应该用哪个来测量墙上时间?

另一个问题是关于cpu时间的。我找到了 clock 很棒的答案,所以我也为它写了一个示例代码。但这不是我真正想要的,因为我的代码显示了 0 秒的 cpu 时间。是否可以更精确地测量 cpu 时间(以秒为单位)?感谢您的帮助(目前,我只对 Linux 解决方案感兴趣)。

这是我的代码:

#include <time.h>
#include <stdio.h>      /* printf */
#include <math.h>       /* sqrt */
#include <stdlib.h>

int main()
{
    int i;
    double sum;

    // measure elapsed wall time
    struct timespec now, tmstart;
    clock_gettime(CLOCK_REALTIME, &tmstart);
    for(i=0; i<1024; i++){
        sum += log((double)i);
    }
    clock_gettime(CLOCK_REALTIME, &now);
    double seconds = (double)((now.tv_sec+now.tv_nsec*1e-9) - (double)(tmstart.tv_sec+tmstart.tv_nsec*1e-9));
    printf("wall time %fs\n", seconds);

    // measure cpu time
    double start = (double)clock() /(double) CLOCKS_PER_SEC;
    for(i=0; i<1024; i++){
        sum += log((double)i);
    }
    double end = (double)clock() / (double) CLOCKS_PER_SEC;
    printf("cpu time %fs\n", end - start);

    return 0;
}

像这样编译:

gcc test.c -o test -lrt -lm

它向我显示:

wall time 0.000424s
cpu time 0.000000s

我知道我可以进行更多迭代,但这不是重点;)

重要提示:

printf("CLOCKS_PER_SEC is %ld\n", CLOCKS_PER_SEC);

显示

CLOCKS_PER_SEC is 1000000

最佳答案

根据我在 clock 上的手册页,它说

POSIX requires that CLOCKS_PER_SEC equals 1000000 independent of the actual resolution.

当在我的计算机上增加迭代次数时,测量的 CPU 时间开始显示在 100000 次迭代时。从返回的数字来看,分辨率似乎实际上是 10 毫秒。

请注意,当您优化代码时,整个循环可能会消失,因为 sum 是一个死值。也没有什么可以阻止编译器在循环中移动 clock 语句,因为它们之间的代码没有真正的依赖关系。

让我详细说明一下代码性能的微观测量。衡量性能的简单而诱人的方法确实是像您所做的那样添加 clock 语句。然而,由于时间在 C 中不是一个概念或副作用,编译器通常可以随意移动这些 clock 调用。为了解决这个问题,很容易让这样的 clock 调用产生副作用,例如让它访问 volatile 变量。然而,这仍然不禁止编译器通过调用移动高度无副作用的免费代码。例如,考虑访问常规局部变量。但更糟糕的是,通过使 clock 调用在编译器看来非常可怕,您实际上会对任何优化产生负面影响。因此,仅仅衡量性能会以负面和不受欢迎的方式影响性能。

如果您使用性能分析,正如某人已经提到的那样,您可以对甚至优化代码的性能进行很好的评估,尽管总体时间当然会增加。

另一种衡量性能的好方法是让编译器报告某些代码将花费的周期数。对于许多体系结构,编译器对此有非常准确的估计。然而,最值得注意的是,对于奔腾架构而言,它不是因为硬件进行了大量难以预测的调度。

虽然这不是常规做法,但我认为编译器应该支持标记要测量的函数的 pragma。然后,编译器可以在函数的序言和结尾中包含高精度的非侵入式测量点,并禁止函数的任何内联。根据架构,它可以选择高精度时钟来测量时间,最好在操作系统的支持下只测量当前进程的时间。

关于c - 如何测量 cpu 时间和挂钟时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17502263/

相关文章:

c - 动态跳转到 C 中的标签

C访问结构中的结构

algorithm - 如何求解递归复杂度T(n) = T(n/4)+T(3n/4)+cn

php - 有关 GMT 伊朗的问题?

C - 字符 *' differs in levels of indirection from ' 字符 (*)[200]

c - Sky mote 的 Contiki Cooja 模拟中的 Energest CPU 读数正在下降

javascript - 避免为每个元素重复使用 javascript

python - 如何让最难的部分在 python 中花费最长的时间

c++ - strlen vs停止为零的字符串操作的性能

c++ - 如何将 chrono::time_point 格式化为字符串