Measuring elapsed time in linux for program c

I am trying to measure elapsed time in Linux. My answer keeps returning zero, which doesn't make sense to me. Below is a way to measure time in my program.

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

main()
{
    double p16 = 1, pi = 0, precision = 1000;
    int k;
    unsigned long micros = 0;
    float millis = 0.0;
    clock_t start, end;
    start = clock();
    // This section calculates pi
    for(k = 0; k <= precision; k++)
    {
        pi += 1.0 / p16 * (4.0 / (8 * k + 1) - 2.0 / (8 * k + 4) - 1.0 / (8 * k + 5) - 1.0 / (8 * k + 6));
        p16 *= 16;
    }
    end = clock();
    micros = end - start;
    millis = micros / 1000;
    printf("%f\n", millis); //my time keeps being returned as 0

    printf("this value of pi is  : %f\n", pi);
}

      

+3


source to share


6 answers


First you need to use floating point arithmetic. Any integer divided by a larger integer value is always zero.

And, of course, you have to do something between the beginning and the end.




By the way, if you have access to gettimeofday

, it is usually preferred over clock

, as it has a higher resolution. Or clock_gettime

, which has an even higher resolution.

+2


source


Three alternatives

  • clock()

  • gettimeofday()

  • clock_gettime()

clock_gettime()

achieves nanosecond precision and supports 4 clock cycles.



  • CLOCK_REALTIME

    System-wide real time clock. Installing this clock requires appropriate privileges.

  • CLOCK_MONOTONIC

    A clock that cannot be set and represents a monotonic time from some unspecified starting point.

  • CLOCK_PROCESS_CPUTIME_ID

    Timer for each process with high resolution from the CPU.

  • CLOCK_THREAD_CPUTIME_ID

    A topic-specific CPU time clock.

You can use it like

#include <time.h>

struct timespec start, stop;

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);

/// do something

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop);

double result = (stop.tv_sec - start.tv_sec) * 1e6 + (stop.tv_nsec - start.tv_nsec) / 1e3;    // in microseconds

      

+6


source


Note. The clock () function returns the processor time for your process, not the wall clock time. I believe this is what the OP was interested in. If wall clock time is required, then gettimeofday () is a good choice as suggested by an earlier answer. Clock_gettime () can use one of them, if your system supports it; on my linux embedded system clock_gettime () is not supported, but clock () and gettimeofday () are.

Below is the code to get wall clock using gettimeofday ()

#include <stdio.h> // for printf()
#include <sys/time.h> // for clock_gettime()
#include <unistd.h> // for usleep()

int main() {
    struct timeval start, end;
    long secs_used,micros_used;

    gettimeofday(&start, NULL);
    usleep(1250000); // Do the stuff you want to time here
    gettimeofday(&end, NULL);

    printf("start: %d secs, %d usecs\n",start.tv_sec,start.tv_usec);
    printf("end: %d secs, %d usecs\n",end.tv_sec,end.tv_usec);

    secs_used=(end.tv_sec - start.tv_sec); //avoid overflow by subtracting first
    micros_used= ((secs_used*1000000) + end.tv_usec) - (start.tv_usec);

    printf("micros_used: %d\n",micros_used);
    return 0;
}

      

+3


source


When you divide, you can get a decimal number, so you need the number of flash points to keep the number of milliseconds. If you are not using floating point, the decimal part will be truncated. In your code snippet, the start and end of ALMOST are the same. Therefore, the result after division when stored in long is "0".

unsigned long micros = 0;
float millis = 0.0;
clock_t start, end;

start = clock();

//code goes here

end = clock();

micros = end - start;
millis = micros / 1000;

      

+1


source


Try Sunil DS's answer, but change microns from unsigned long to float or double, like so:

double micros;
float seconds;

clock_t start, end;

start = clock();

/* Do something here */

end = clock();

micros = end - start;
seconds = micros / 1000000;

      

Alternatively, you can use rusage, for example:

struct rusage before;

struct rusage after;

float a_cputime, b_cputime, e_cputime;

float a_systime, b_systime, e_systime;

getrusage(RUSAGE_SELF, &before);

/* Do something here! or put in loop and do many times */

getrusage(RUSAGE_SELF, &after);

a_cputime = after.ru_utime.tv_sec + after.ru_utime.tv_usec / 1000000.0;

b_cputime = before.ru_utime.tv_sec + before.ru_utime.tv_usec / 1000000.0;

e_cputime = a_cputime - b_cputime;

a_systime = after.ru_stime.tv_sec + after.ru_stime.tv_usec / 1000000.0;

b_systime = before.ru_stime.tv_sec + before.ru_stime.tv_usec / 1000000.0;

e_systime = a_systime - b_systime;


printf("CPU time (secs): user=%.4f; system=%.4f; real=%.4f\n",e_cputime, e_systime, seconds);

      

The units and accuracy depend on how long you want to measure, but either should provide reasonable accuracy for ms.

0


source


There are two problems written in the code.

  • According to the man 3 clock

    resolution clock()

    is CLOCKS_PER_SEC

    in increments per second. On the Cygwin system this is 200 lately. Based on your variable names, you would expect the value to be 1,000,000.

  • This line:

    millis = micros / 1000;
    
          

    will evaluate the quotient as an integer since both operands are integers. Advancement to a floating point type occurs during assignment millis

    , after which the fractional part is already discarded.

To calculate the number of seconds elapsed using clock()

you need to do something like this:

clock_t start, end;
float seconds;
start = clock();
// Your code here:
end = clock();
seconds = end - start; // time difference is now a float
seconds /= CLOCKS_PER_SEC; // this division is now floating point

      

However, you almost certainly won't get millisecond precision. To do this, you will need to use gettimeofday()

or clock_gettime()

. Also, you probably want to use double

instead float

, because you will most likely end up subtracting very large numbers with very little difference. Example using clock_gettime()

:

#include <time.h>
/* Floating point nanoseconds per second */
#define NANO_PER_SEC 1000000000.0

int main(void)
{
    struct timespec start, end;
    double start_sec, end_sec, elapsed_sec;
    clock_gettime(CLOCK_REALTIME, &start);
    // Your code here
    clock_gettime(CLOCK_REALTIME, &end);
    start_sec = start.tv_sec + start.tv_nsec/NANO_PER_SEC;
    end_sec = end.tv_sec + end.tv_n_sec/NANO_PER_SEC;
    elapsed_sec = end_sec - start_sec;
    printf("The operation took %.3f seconds\n", elapsed_sec);
    return 0;
}

      

Since NANO_PER_SEC

is a floating point value, division operations are performed in floating point.

Sources:
man

pages for clock(3)

, gettimeofday(3)

and clock_gettime(3)

.
The C Programming Language, Kernighan and Ritchie

0


source







All Articles