2010-09-11 2 views
2

У меня есть определенная функция (ну, набор функций), которую я хочу запустить каждые 400 мс. Я не очень программист на С, и поэтому все, что находится за пределами стандартных библиотек, является для меня загадкой, а также совсем немного внутри них.Как измерить продолжительность выполнения функции (linux C)?

Моя первая мысль - использовать nanosleep для приостановки выполнения в течение 400 мс в каком-то цикле, но это, конечно, не учитывает время выполнения кода, который я буду запускать. Если бы я мог измерить его, и если бы он казался вполне уверенным, что он работал в течение той же приблизительной продолжительности после 10 или 20 тестов, я мог бы затем наносить() разницу. Конечно, это было бы не идеально, но, возможно, это было бы достаточно близко для первой попытки.

Как измерить время выполнения функции C? Или есть лучший способ сделать это в целом, и какие ключевые слова мне нужно искать?

+1

Вы можете попробовать ftime() до и после вызова функции, а затем вычесть оба раза. Это не тривиально, поскольку у вас есть 2 поля «секунды» и «миллис» – LatinSuD

ответ

4

Вы должны быть в состоянии использовать settimer

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

Просто поместите код, который вы хотите выполнить каждые 400ms внутри обработчика 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; 
} 
+0

'pause()' лучше, чем 'sleep (1)' там. – caf

1

Посмотрите на gprof. Он позволяет быстро перекомпилировать ваш код и генерировать информацию о том, какие функции вызывают и что занимает больше всего времени в вашей программе.

+1

Это, вероятно, намного лучшая альтернатива, чем распыление вокруг большого количества вызовов таймера внутри кода. Люди должны использовать себя для запуска отладчиков и профилировщиков вместо того, чтобы записывать множество строк отладки в своем коде. – alecov

0

Вы можете использовать gettimeofday() или clock_gettime() до и после функций во времени, а затем рассчитать дельту между двумя раз.

0

Для Linux вы можете использовать gettimeofday. Вызовите gettimeofday в начале функции. Запустите все, что вам нужно запустить. Затем получите время окончания и выясните, сколько еще вам нужно спать. Затем вызовите sleep для соответствующего количества микросекунд.

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; 
} 
Смежные вопросы