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);
}
source to share
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.
source to share
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
source to share
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;
}
source to share
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;
source to share
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.
source to share
There are two problems written in the code.
-
According to the
man 3 clock
resolutionclock()
isCLOCKS_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
source to share