【问题标题】:How to use c time in linux to print the function running time?如何在linux中使用c时间打印函数运行时间?
【发布时间】:2011-11-23 09:38:51
【问题描述】:

我在linux下运行c代码时,代码总是不打印经过时间,结果总是0。代码如下:

#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void main(int argc,char* argv[]){
  int n;
  if(argc == 2){
    n = atoi(argv[1]);
  }
  struct timeval start, end;
  gettimeofday(&start, 0);
  int r = fib(n);
  gettimeofday(&end, 0);
  long mtime, s,us;
  s = end.tv_sec  - start.tv_sec;
  us = end.tv_usec - start.tv_usec;
  printf("s=%f,us=%f  \n", s, us);
  mtime = (s*1000 + us/1000.0)+0.5;
  printf("Fib result for %d is: %d;elapsing %f \n", n, r, mtime); 

}

int fib(int n){
  if(n == 0) return 0;
  if(n == 1) return 1;
  return fib(n-1)+fib(n-2);
}

【问题讨论】:

    标签: c linux time


    【解决方案1】:

    所有建议实际上都有效,但时间测量的粒度很大(通常为 10 到 100 毫秒)。因此,它实际上测量了一些持续时间的计算,例如半秒钟。在当前的处理器上(以 2 到 3Ghz 运行,每个周期大约 3-5 条指令),这意味着执行了大约十亿条机器指令(我们的 C 程序中的“基本步骤”——通常有一个定义不明确的步骤概念)十几个机器指令)。所以你的测试太小了,你真的应该计算一百万次 fibion​​acci (10)。

    更具体地说,下面的程序(输出一些计算,以避免全部优化)运行大约 2 秒。 (对小于 16 的斐波那契数百万次计算)。

    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    long fib(int n){
      if(n == 0) return 0;
      if(n == 1) return 1;
      return fib(n-1)+fib(n-2);
    }
    
    int main ()
    {
      int i=0;
      int p = (int) getpid();
      clock_t cstart = clock();
      clock_t cend = 0;
      for (i=0; i<1000000; i++) {
        long f = fib(i%16);
        if (i % p == 0) printf("i=%d, f=%ld\n", i, f);
      }
      cend = clock();
      printf ("%.3f cpu sec\n", ((double)cend - (double)cstart)* 1.0e-6);
      return 0;
    }   
    

    最后几行输出为time ./fib(编译为gcc -O2 -Wall fib.c -o fib) 是

    i=936079, f=610
    i=948902, f=8
    i=961725, f=233
    i=974548, f=3
    i=987371, f=89
    2.140 cpu sec
    ./fib  2.15s user 0.00s system 99% cpu 2.152 total
    

    对小于约一秒的运行进行基准测试没有多大意义

    (您可以使用time 命令来测量这样的运行)

    另见time(7)clock_gettime(2)

    【讨论】:

      【解决方案2】:

      不要忽视编译器警告;您正在尝试打印三个 long 变量(mtimesus),就好像它们是 doubles:

      fib.c: In function ‘main’:
      fib.c:17:3: warning: format ‘%f’ expects type ‘double’, but argument 2 has type ‘long int’
      fib.c:17:3: warning: format ‘%f’ expects type ‘double’, but argument 3 has type ‘long int’
      fib.c:19:3: warning: format ‘%f’ expects type ‘double’, but argument 4 has type ‘long int’
      

      sus更改为long,并将sus的格式更改为%ld,程序编译(并运行)无误。

      【讨论】:

        【解决方案3】:

        使用clock 函数可能更容易:

        clock_t start = clock();
        int r = fib(n);
        clock_t end = clock();
        printf("Elapsed time: %.2f seconds\n", (double)(end - start) / CLOCKS_PER_SEC);
        

        【讨论】:

        • clock() 是否提供处理器使用的时间或经过的时间?
        • @AlessandroPezzato 根据手册页(链接到答案):clock() 函数返回程序使用的处理器时间的近似值。
        • clock 测量 CPU 时间,而不是挂钟时间。这可能不是问题所在。
        【解决方案4】:

        实时时钟的分辨率可能不是非常小(可能是 10 或 25 毫秒),而且您的计算太短而没有意义。您可以将计算放入一个循环中(例如重复数千次)。

        您还可以考虑使用clock 函数测量CPU 时间。

        您还可以使用clock_gettime 函数来获得更好的结果。

        正如其他人告诉你的那样,请使用gcc -Wall 询问所有警告并将其考虑在内。如果您关心性能(但请记住,过早的优化是邪恶的,所以首先要让您的程序正确!)考虑在编译期间启用优化(例如gcc -Wall -O2)。

        【讨论】:

        • 说实话,我可以为斐波那契函数输入一个很好的数字,但即使我给它一个数字,比如50,结果时间仍然是0.0000
        • 你是否重复调用斐波那契一百万次?
        【解决方案5】:

        这应该给你经过的时间:

        #include <iostream>
        #include <sys/time.h> /* gettimeofday */
        
        int main() {
            /* get begin time */
            timeval begin;
            ::gettimeofday(&begin, 0);
            /* do something... */
            ::usleep(153);
            /* get end time */
            ::timeval current;
            ::gettimeofday(&current, (struct timezone*) 0);
            /* calculate difference */
            double elapsed = (current.tv_sec - begin.tv_sec) + ((current.tv_usec
                    - begin.tv_usec) / 1000000.0F);
            /* print it */
            std::cout << elapsed << std::endl;
            return 0;
        }
        

        【讨论】:

        • 我在c中尝试了这个方法,它确实有效,但是当我像我发布的代码一样使用它时,它竟然不起作用
        猜你喜欢
        • 2014-09-10
        • 1970-01-01
        • 1970-01-01
        • 2017-11-06
        • 1970-01-01
        • 1970-01-01
        • 2011-07-11
        • 1970-01-01
        • 2023-03-05
        相关资源
        最近更新 更多