2010-09-11 86 views
2

我有一个特定的功能(以及一组函数),我想每400ms启动一次。我不是一个C程序员,因此标准库之外的任何东西对我来说都是一个谜,也是其中的一大谜。如何测量(linux C)函数执行多长时间?

我的第一个想法是使用nanosleep在某种循环中暂停执行400ms,但这当然不考虑我将运行的代码的执行时间。如果我可以测量它,并且如果它在10或20次测试后运行相同的大致持续时间似乎相当确定,那么我可以纳秒睡眠()来获得差异。这当然不会是完美的......但它可能足够接近第一次尝试。

如何测量C函数的执行时间?或者是否有更好的方法来完成这项工作,以及我需要使用哪些关键字进行搜索?

+1

您可以在调用函数之前和之后尝试ftime(),然后减去两次。这不是微不足道的,因为你有两个字段“秒”和“毫秒” – LatinSuD 2010-09-11 22:11:38

回答

4

您应该能够使用settimer

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

只要把要执行SIGALRM处理程序中的每400毫秒的代码。这样您就不需要考虑代码运行的时间,这可能会有所不同。我不确定如果信号处理程序在下一个信号生成之前没有返回会发生什么情况。

下面显示了一些代码的外观大纲。

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; 
} 
+0

'暂停()'比'睡眠(1)'好。 – caf 2010-09-12 00:45:40

1

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

+1

这可能是一个更好的选择,而不是在代码中喷洒很多定时器。人们应该习惯于运行调试器和分析器,而不是在代码中记录大量调试字符串。 – alecov 2010-09-12 02:25:59

0

对于Linux,您可以使用gettimeofday。在函数的开始处调用gettimeofday。运行你必须运行的任何东西。然后获得结束时间,并计算出你需要睡多久。然后调用usleep适当的微秒数。

0

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

您可以使用setitimer执行相同的功能,但您也可以使用timer_getoverrun()来让您知道是否在函数期间错过了任何计时器事件。

1

我同意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; 
}