Время выполнения программы C

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

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

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

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

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

Спасибо

Ответ 1

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() не измеряет одно и то же. Это "настенные часы": это может помочь вам измерить, сколько времени потребовалось для выполнения программы, но это не говорит вам, сколько времени было использовано для процессора. В многозадачных системах (т.е. Все они) они могут быть разными.

Ответ 2

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

делать

$ time ./a.out

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

Ответ 3

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

#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));

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

Ответ 4

В простой ваниле 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;
}

Ответ 5

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

#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

Ответ 6

Многие ответы предлагали 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, в зависимости от того, какие параметры вы используете для компиляции, и, следовательно, это не похоже на хорошее решение.

Ответ 7

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

#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.

Ответ 8

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

Зная, что способ получения текущего времени в 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));
}

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

Привет!

Ответ 9

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

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

Ответ 10

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

В 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.

Ответ 11

Каждое решение не работает в моей системе.

Я могу использовать

#include <time.h>

double difftime(time_t time1, time_t time0);

Ответ 12

    #include<time.h>
    #include<stdio.h>
    int main(){
clock_t begin=clock();

    int i;
for(i=0;i<100000;i++){
printf("%d",i);

}
clock_t end=clock();
printf("Time taken:%lf",(double)(end-begin)/CLOCKS_PER_SEC);
}

Эта программа будет работать как прелесть.

Ответ 13

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

Таким образом, единственный способ надежно получать один и тот же результат каждый раз с помощью clock() - это запускать измеренный код в цикле несколько раз (в течение нескольких минут), принимая меры предосторожности, чтобы не допустить его оптимизации компилятором: современные компиляторы могут предварительно вычислять код без побочных эффектов, запущенных в цикле, и выведите его из цикла. Например, используйте случайный ввод для каждой итерации.

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

Вот простая утилита для измерения производительности выполнения кода C/C++ с усреднением значений, близких к медиане: https://github.com/saniv/gauge

Я сам все еще ищу более надежный и быстрый способ измерения кода. Вероятно, можно попробовать запустить код в контролируемых условиях на голом железе без какой-либо ОС, но это даст нереальный результат, потому что в действительности ОС действительно вмешивается.

В x86 есть эти аппаратные счетчики производительности, которые включают фактическое количество выполненных инструкций, но их сложно получить без помощи ОС, сложно интерпретировать и у них есть свои проблемы (http://archive.gamedev.net/archive/reference/articles/article213.html). Тем не менее, они могут быть полезны при изучении природы горлышка бутылки (доступ к данным или фактические вычисления на этих данных).

Ответ 14

Некоторым может пригодиться другой вид ввода: мне дали этот метод измерения времени как часть университетского курса по программированию GPGPU с NVidia CUDA (описание курса). Он объединяет методы, которые видели в предыдущих публикациях, и я просто публикую его, потому что требования придают ему достоверность:

unsigned long int elapsed;
struct timeval t_start, t_end, t_diff;
gettimeofday(&t_start, NULL);

// perform computations ...

gettimeofday(&t_end, NULL);
timeval_subtract(&t_diff, &t_end, &t_start);
elapsed = (t_diff.tv_sec*1e6 + t_diff.tv_usec);
printf("GPU version runs in: %lu microsecs\n", elapsed);

Я полагаю, вы могли бы умножить, например, на 1.0/1000.0 чтобы получить единицу измерения, которая соответствует вашим потребностям.

Ответ 15

Сравнение времени выполнения сортировки и сортировки пузырьков У меня есть программа, которая сравнивает время выполнения сортировки и сортировки пузырьков. Чтобы узнать время выполнения блока кода, вычислить время до и после блока с помощью

 clock_t start=clock();
 …
 clock_t end=clock();
 CLOCKS_PER_SEC is constant in time.h library

Пример кода:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
   int a[10000],i,j,min,temp;
   for(i=0;i<10000;i++)
   {
      a[i]=rand()%10000;
   }
   //The bubble Sort
   clock_t start,end;
   start=clock();
   for(i=0;i<10000;i++)
   {
     for(j=i+1;j<10000;j++)
     {
       if(a[i]>a[j])
       {
         int temp=a[i];
         a[i]=a[j];
         a[j]=temp;
       }
     }
   }
   end=clock();
   double extime=(double) (end-start)/CLOCKS_PER_SEC;
   printf("\n\tExecution time for the bubble sort is %f seconds\n ",extime);

   for(i=0;i<10000;i++)
   {
     a[i]=rand()%10000;
   }
   clock_t start1,end1;
   start1=clock();
   // The Selection Sort
   for(i=0;i<10000;i++)
   {
     min=i;
     for(j=i+1;j<10000;j++)
     {
       if(a[min]>a[j])
       {
         min=j;
       }
     }
     temp=a[min];
     a[min]=a[i];
     a[i]=temp;
   }
   end1=clock();
   double extime1=(double) (end1-start1)/CLOCKS_PER_SEC;
   printf("\n");
   printf("\tExecution time for the selection sort is %f seconds\n\n", extime1);
   if(extime1<extime)
     printf("\tSelection sort is faster than Bubble sort by %f seconds\n\n", extime - extime1);
   else if(extime1>extime)
     printf("\tBubble sort is faster than Selection sort by %f seconds\n\n", extime1 - extime);
   else
     printf("\tBoth algorithms have the same execution time\n\n");
}