Как измерить, сколько времени занимает (linux C) функция для выполнения? - PullRequest
2 голосов
/ 12 сентября 2010

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

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

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

Ответы [ 6 ]

4 голосов
/ 12 сентября 2010

Вы должны использовать 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;
}
1 голос
/ 12 сентября 2010

Я согласен с торак об использовании 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;
}
1 голос
/ 12 сентября 2010

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

0 голосов
/ 12 сентября 2010

Посмотрите на таймеры POSIX. Вот некоторая документация на HP .

Вы можете выполнять те же функции, что и с setitimer, но у вас также есть timer_getoverrun (), чтобы сообщить вам, пропустили ли вы какие-либо события таймера во время вашей функции.

0 голосов
/ 12 сентября 2010

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

0 голосов
/ 12 сентября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...