Czas wykonania programu C

Mam program C, który ma być uruchamiany równolegle na kilku procesorach. Muszę mieć możliwość rejestrowania czasu wykonania (który może wynosić od 1 sekundy do kilku minut). Szukałem odpowiedzi, ale wszystkie wydają się sugerować użycie funkcji clock(), która następnie polega na obliczaniu liczby zegarów, które program pobrał, podzielonej przez wartość Clocks_per_second.

Nie jestem pewien, jak obliczana jest wartość Clocks_per_second?

W Javie, biorę bieżący czas w milisekundach przed i po egzekucji.

Jest coś podobnego w C? Spojrzałem, ale nie mogę znaleźć sposobu na uzyskanie czegoś lepszego niż druga rozdzielczość.

Wiem również, że profiler byłby opcją, ale sam chciałbym zaimplementować timer.

Dzięki

 155
Author: Mohan, 2011-03-09

13 answers

CLOCKS_PER_SEC jest stałą zadeklarowaną w <time.h>. Aby uzyskać czas procesora używany przez zadanie w aplikacji C, użyj:

clock_t begin = clock();

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

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

Zwróci czas jako typ zmiennoprzecinkowy. Może to być dokładniejsze niż sekunda(np. mierzysz 4,52 sekundy). Precyzja zależy od architektury; na nowoczesnych systemach można łatwo uzyskać 10ms lub mniej, ale na starszych maszynach Windows (z ery Win98) było bliżej 60ms.

clock() jest standardem C; działa "wszędzie". Są funkcje specyficzne dla systemu, takie jak getrusage() w systemach uniksopodobnych.

Java System.currentTimeMillis() nie mierzy tego samego. Jest to "zegar ścienny": może pomóc zmierzyć, ile czasu zajęło wykonanie programu, ale nie mówi, ile czasu procesora zostało wykorzystane. W systemach wielozadaniowych (tj. WSZYSTKICH) mogą one być bardzo różne.

 272
Author: Thomas Pornin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-27 20:44:17

Jeśli używasz powłoki Uniksa do działania, możesz użyć polecenia time.

Robienie

$ time ./a.out

Założenie a. out jako pliku wykonywalnego Da U czas potrzebny na uruchomienie tego

 93
Author: S..K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-09 16:47:11

Chcesz tego:

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

Zauważ, że mierzy się to w mikrosekundach, a nie tylko sekundach.

 48
Author: Wes Hardaker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-31 11:14:10

In plain vanilla 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;
}
 48
Author: Alexandre C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 09:33:02

Większość prostych programów ma czas obliczeń w mili-sekundach. Więc, przypuszczam, że uznasz to za przydatne.

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

Jeśli chcesz obliczyć runtime całego programu i jesteś w systemie Unix, Uruchom swój program za pomocą time w następujący sposób time ./a.out

 10
Author: adimoh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-29 17:05:02

Wiele odpowiedzi sugerowało clock(), a następnie CLOCKS_PER_SEC z time.h. To chyba zły pomysł, bo tak pisze mój plik /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

Więc CLOCKS_PER_SEC może być zdefiniowane jako 1000000, w zależności od opcji, których używasz do kompilacji, a więc nie wydaje się to dobrym rozwiązaniem.

 7
Author: Stephen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-08 18:35:04

Należy wziąć pod uwagę, że pomiar czasu , który zajął wykonanie programu, zależy w dużej mierze od obciążenia maszyny w danym momencie.

Wiedząc, że sposób uzyskania bieżącego czasu w C można osiągnąć na różne sposoby, łatwiej jest:

#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));
}
Mam nadzieję, że to pomoże. Pozdrawiam!
 3
Author: redent84,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-30 23:23:21

ANSI C określa tylko funkcje czasu drugiej precyzji. Jednakże, jeśli pracujesz w środowisku POSIX, możesz użyć funkcji gettimeofday () , która zapewnia rozdzielczość mikrosekund czasu upływającego od epoki Uniksa.

Na marginesie, nie polecam używania clock (), ponieważ jest źle zaimplementowana na wielu(jeśli nie wszystkich?) systemów i nie dokładne, poza tym, że odnosi się tylko do tego, jak długo Twój program spędził na procesorze, a nie całkowitej żywotności program, który zgodnie z twoim pytaniem jest, co zakładam, że chcesz zmierzyć.

 3
Author: Shinnok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-30 23:57:56

Każde rozwiązanie nie działa w moim systemie.

I can get using

#include <time.h>

double difftime(time_t time1, time_t time0);
 2
Author: Ankit Chilamatur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-05 04:21:30
    #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);
}

Ten program będzie działał jak urok.

 2
Author: Ravi Kumar Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-03 17:03:47

(wszystkich odpowiedzi tutaj brakuje, Jeśli twój sysadmin zmienia czas systemowy, lub Twoja strefa czasowa ma różny czas zimowy i sommer. Dlatego...)

Użycie Linuksa: clock_gettime(CLOCK_MONOTONIC_RAW, &time_variable); Nie ma to wpływu, jeśli system-admin zmienia czas, lub mieszkasz w kraju, w którym czas zimowy różni się od letniego, itp.

#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 Stany:

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.
 1
Author: JohnSll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-31 13:46:08

Odpowiedź Tomasza Pornina jako makra:

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

Użyj go tak:

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

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

Wyjście:

time TIME_A: 0.001652 sec.
time TIME_B: 0.004028 sec.
 1
Author: Alex Ling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-21 13:11:32

Porównanie czasu wykonania sortowania bąbelkowego i sortowania selekcji Mam program, który porównuje czas wykonania sortowania bąbelkowego i sortowania selekcji. Aby sprawdzić czas wykonania bloku kodu, Oblicz czas przed i po bloku przez

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

Przykładowy kod:

#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");
}
 0
Author: JAGDISH DUDHATE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-05 01:19:58