Время выполнения C программы - PullRequest
186 голосов
/ 09 марта 2011

У меня есть программа на C, которая предназначена для параллельной работы на нескольких процессорах. Мне нужно иметь возможность записывать время выполнения (которое может быть от 1 секунды до нескольких минут). Я искал ответы, но все они, кажется, предлагают использовать функцию clock(), которая затем включает в себя подсчет количества тактов, которые программа взяла, деленного на значение Clocks_per_second.

Я не уверен, как рассчитывается значение Clocks_per_second?

В Java я просто беру текущее время в миллисекундах до и после выполнения.

Есть ли подобное в C? Я посмотрел, но я не могу найти способ получить что-то лучше, чем второе разрешение.

Я также знаю, что в качестве опции можно использовать профилировщик, но я сам собираюсь реализовать таймер.

Спасибо

Ответы [ 14 ]

304 голосов
/ 09 марта 2011

CLOCKS_PER_SEC - это константа, объявленная в <time.h>. Чтобы получить процессорное время, используемое задачей в приложении C, используйте:

clock_t begin = clock();

/* here, do your time-consuming job */

clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

Обратите внимание, что это возвращает время как тип с плавающей запятой. Это может быть более точным, чем секунда (например, вы измеряете 4,52 секунды). Точность зависит от архитектуры; в современных системах вы легко получаете 10 мс или меньше, но на старых машинах Windows (из эпохи Win98) оно было ближе к 60 мс.

clock() - стандарт C; это работает "везде". Существуют системные функции, такие как getrusage() в Unix-подобных системах.

Java System.currentTimeMillis() не измеряет одно и то же. Это «настенные часы»: они могут помочь вам измерить, сколько времени потребовалось для выполнения программы, но они не сообщают вам, сколько процессорного времени было использовано. В многозадачных системах (то есть во всех них) они могут сильно различаться.

106 голосов
/ 09 марта 2011

Если вы используете оболочку Unix для запуска, вы можете использовать команду времени.

делает

$ time ./a.out

, предполагая, что a.out в качестве исполняемого файла даст вам время, необходимое длязапустить это

57 голосов
/ 09 марта 2011

Вы функционально хотите это:

#include <sys/time.h>

struct timeval  tv1, tv2;
gettimeofday(&tv1, NULL);
/* stuff to do! */
gettimeofday(&tv2, NULL);

printf ("Total time = %f seconds\n",
         (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
         (double) (tv2.tv_sec - tv1.tv_sec));

Обратите внимание, что это измеряется в микросекундах, а не в секундах.

54 голосов
/ 09 марта 2011

В простой ванили C:

#include <time.h>
#include <stdio.h>

int main()
{
    clock_t tic = clock();

    my_expensive_function_which_can_spawn_threads();

    clock_t toc = clock();

    printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);

    return 0;
}
12 голосов
/ 17 июня 2013

Большинство простых программ имеют время вычисления в миллисекундах. Итак, я полагаю, вы найдете это полезным.

#include <time.h>
#include <stdio.h>

int main(){
    clock_t start = clock();
    // Execuatable code
    clock_t stop = clock();
    double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
    printf("Time elapsed in ms: %f", elapsed);
}

Если вы хотите вычислить время выполнения всей программы и работаете в системе Unix, запустите вашу программу с помощью команды time , подобной этой time ./a.out

9 голосов
/ 08 ноября 2012

Многие ответы предлагали clock(), а затем CLOCKS_PER_SEC из time.h.Вероятно, это плохая идея, потому что это то, что говорит мой /bits/time.h файл:

/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
#  define CLOCKS_PER_SEC  1000000l

#  if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K
/* Even though CLOCKS_PER_SEC has such a strange value CLK_TCK
presents the real value for clock ticks per second for the system.  */
#   include <bits/types.h>
extern long int __sysconf (int);
#   define CLK_TCK ((__clock_t) __sysconf (2))  /* 2 is _SC_CLK_TCK */
#  endif

Так что CLOCKS_PER_SEC может быть определено как 1000000, в зависимости от того, какие опции вы используете для компиляции, и поэтомуне кажется хорошим решением.

8 голосов
/ 21 января 2018

Томас Порнин ответил как макрос:

#define TICK(X) clock_t X = clock()
#define TOCK(X) printf("time %s: %g sec.\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC)

Используйте это так:

TICK(TIME_A);
functionA();
TOCK(TIME_A);

TICK(TIME_B);
functionB();
TOCK(TIME_B);

Выход:

time TIME_A: 0.001652 sec.
time TIME_B: 0.004028 sec.
4 голосов
/ 09 марта 2011

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

Зная, чтоСпособ получения текущего времени в C может быть достигнут различными способами, более простым является:

#include <time.h>

#define CPU_TIME (getrusage(RUSAGE_SELF,&ruse), ruse.ru_utime.tv_sec + \
  ruse.ru_stime.tv_sec + 1e-6 * \
  (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec))

int main(void) {
    time_t start, end;
    double first, second;

    // Save user and CPU start time
    time(&start);
    first = CPU_TIME;

    // Perform operations
    ...

    // Save end time
    time(&end);
    second = CPU_TIME;

    printf("cpu  : %.2f secs\n", second - first); 
    printf("user : %d secs\n", (int)(end - start));
}

Надеюсь, это поможет.

С уважением!

3 голосов
/ 31 января 2017

(Все ответы здесь отсутствуют, если ваш системный администратор меняет системное время или ваш часовой пояс отличается по времени зимы и лета. Поэтому ...)

При использовании Linux: clock_gettime(CLOCK_MONOTONIC_RAW, &time_variable); Это не влияетесли системный администратор меняет время, или вы живете в стране, где зимнее время отличается от летнего и т. д.

#include <stdio.h>
#include <time.h>

#include <unistd.h> /* for sleep() */

int main() {
    struct timespec begin, end;
    clock_gettime(CLOCK_MONOTONIC_RAW, &begin);

    sleep(1);      // waste some time

    clock_gettime(CLOCK_MONOTONIC_RAW, &end);

    printf ("Total time = %f seconds\n",
            (end.tv_nsec - begin.tv_nsec) / 1000000000.0 +
            (end.tv_sec  - begin.tv_sec));

}

man clock_gettime говорится:

CLOCK_MONOTONIC
              Clock  that  cannot  be set and represents monotonic time since some unspecified starting point.  This clock is not affected by discontinuous jumps in the system time
              (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP.
3 голосов
/ 09 марта 2011

ANSI C определяет только функции времени с второй точностью. Однако, если вы работаете в среде POSIX, вы можете использовать функцию gettimeofday () , которая обеспечивает разрешение микросекунд времени, прошедшего с начала эпохи UNIX.

В качестве примечания, я бы не рекомендовал использовать clock (), поскольку он плохо реализован во многих (если не во всех?) Системах и не точен, за исключением того, что он относится только к тому, сколько времени ваша программа потратила на ЦП, а не общее время жизни программы, которое, как я полагаю, вы хотите измерить в соответствии с вашим вопросом.

...