代码之家  ›  专栏  ›  技术社区  ›  John O

如何度量(LinuxC)函数执行所需的时间?

  •  2
  • John O  · 技术社区  · 14 年前

    我有一个特定的函数(好的,一组函数),我想每400毫秒启动一次。我不是一个C程序员,所以标准库之外的任何东西对我来说都是一个谜,在它们里面也是一个谜。

    我的第一个想法是使用nanosleep在某种循环中暂停执行400毫秒,但这当然没有考虑到我将运行的代码的执行时间。如果我可以测量它,如果它在10或20次测试后运行相同的大致持续时间,那么我可以用nanosleep()来计算差异。当然,这不是完美的…但它可能足够接近第一次尝试。

    如何测量C函数的执行时间?或者有更好的方法来完成这一切,我需要谷歌搜索什么关键字?

    6 回复  |  直到 14 年前
        1
  •  4
  •   torak    14 年前

    你应该能用 settimer

    int setitimer(int which, const struct itimerval *value,
                  struct itimerval *ovalue);
    

    只需将您希望每隔400毫秒执行一次的代码放入sigalrm处理程序。这样,您就不需要考虑代码运行所需的时间,这可能会有所不同。我不确定如果信号处理程序在生成下一个信号之前不返回会发生什么。

    下面显示了一些代码的大致情况。

    void periodic_fuc(int signal_num)
    {
      ...
      signam(SIGALRM, periodic_func);
    }
    
    int main(...)
    {
      struct itimerval timerval = {0};
    
      signal(SIGALRM, periodic_func);      
      ...
      timerval.it_interval.tv_usec = 400000;
      timerval.it_value.tv_usec = 400000; // Wait 400ms for first trigger
      settimer(ITIMER_REAL, &timerval, NULL);
    
      while (!exit)
        sleep(1);
      return 0;
    }
    
        2
  •  1
  •   Michael Mior    14 年前

    看一看 gprof . 它允许您快速重新编译代码并生成有关调用哪些函数以及在程序中占用最多时间的信息。

        3
  •  1
  •   Community chadoh    7 年前

    我同意。 torak 关于使用 setitimer() . 但是,由于不清楚间隔是否在 SIGALRM 处理程序 出口 无论如何,你不应该在一个信号处理程序中做太多的工作,最好设置一个标志,然后在主例程中进行工作:

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <unistd.h>
    #include <sys/time.h>
    
    volatile sig_atomic_t wakeup = 0;
    
    void alarm_handler(int signal_num)
    {
        wakeup = 1;
    }
    
    int main()
    {
        struct itimerval timerval = { 0 };
        struct sigaction sigact = { 0 };
        int finished = 0;
    
        timerval.it_interval.tv_usec = 400000;
        timerval.it_value.tv_usec = 400000;
    
        sigact.sa_handler = alarm_handler;
    
        sigaction(SIGALRM, &sigact, NULL);
        setitimer(ITIMER_REAL, &timerval, NULL);
    
        while (!finished)
        {
            /* Wait for alarm wakeup */
            while (!wakeup)
                pause();
            wakeup = 0;
    
            /* Code here... */
            printf("(Wakeup)\n");
        }
    
        return 0;
    }
    
        4
  •  0
  •   Jonathan Leffler Toon Krijthe    14 年前

    你可以使用 gettimeofday() clock_gettime() 函数前后要计时,然后计算两次之间的增量。

        5
  •  0
  •   Jonathan Sternberg    14 年前

    对于Linux,您可以使用 gettimeofday . 在函数开始时调用GetTimeOfDay。跑任何你必须跑的。然后得到结束时间,计算出你还要睡多久。然后调用usleep以获得适当的微秒数。

        6
  •  0
  •   Zan Lynx    14 年前

    看看POSIX计时器。这里是 some documentation at HP .

    您可以使用setitimer执行相同的函数,但是您还可以使用timer_GetOverrun()来通知您是否在函数期间错过了任何计时器事件。