gettimeofday to calculate elapsed when day changes - c

The typical example that I see when trying to do measure elapsed time goes something like this:
#include <sys/time.h>
#include <stdio.h>
int main() {
struct timeval start, end;
gettimeofday(&start, NULL);
//Do some operation
gettimeofday(&end, NULL);
unsigned long long end_time = (end.tv_sec * 1000000 + end.tv_usec);
unsigned long long start_time = (start.tv_sec * 1000000 + start.tv_usec);
printf("Time taken : %ld micro seconds\n", end_time - start_time);
return 0;
}
This is great when it's somewhere mid day, but if someone were to run some tests late at night this wouldn't work. My approach is something like this to address it:
#include <sys/time.h>
#include <stdio.h>
int main() {
struct timeval start, end;
gettimeofday(&start, NULL);
//Do some operation
gettimeofday(&end, NULL);
unsigned long long end_time = (end.tv_sec * 1000000 + end.tv_usec);
unsigned long long start_time = (start.tv_sec * 1000000 + start.tv_usec);
unsigned long long elapsed_time = 0;
if ( end_time < start_time )
//Made up some constant that defines 86,400,000,000 microseconds in a day
elapsed_time = end_time + (NUM_OF_USEC_IN_A_DAY - start_time);
else
elapsed_time = end_time - start_time;
printf("Time taken : %ld micro seconds\n", elapsed_time);
return 0;
}
Is there a better way of anticipating day change using gettimeofday?

Despite the name, gettimeofday results do not roll over daily. The gettimeofday seconds count, just like the time seconds count, started at zero on the first day of 1970 (specifically 1970-01-01 00:00:00 +00:00) and has been incrementing steadily ever since. On a system with 32-bit time_t, it will roll over sometime in 2038; people are working right now to phase out the use of 32-bit time_t for this exact reason and we expect to be done well before 2038.
gettimeofday results are also independent of time zone and not affected by daylight savings shifts. They can go backward when the computer's clock is reset. If you don't want to worry about that, you can use clock_gettime(CLOCK_MONOTONIC) jnstead.

Why would you want to handle the case where end.tv_sec is less than start.tv_sec? Are you trying to account for ntpd changes? If so, and especially if you want to record only elapsed time, then use clock_gettime instead of gettimeofday as the former is immune to wall clock changes.

but if someone were to run some tests late at night this wouldn't work
That's an incorrect statement because gettimeofday is not relative to the start of each day but rather relative to a fixed point in time. From the gettimeofday manual:
gives the number of seconds and microseconds since the Epoch
So the first example will work as long as there are no jumps in time (e.g. due to manual time setting or NTP). Again from the manual:
The time returned by gettimeofday() is affected by discontinuous
jumps in the system time (e.g., if the system administrator manually
changes the system time). If you need a monotonically increasing
clock, see clock_gettime(2).

Is there a better way of anticipating day change using gettimeofday?
In addition to other problems identified in various answers, the following is also subject integer overflow when time_t is only 32-bit. Instead scale by a (unsigned) long long constant.
// unsigned long long end_time = (end.tv_sec * 1000000 + end.tv_usec);
long long end_time = (end.tv_sec * 1000000ll + end.tv_usec);
// Use correct specifier, not %ld for unsigned long long
// printf("Time taken : %ld micro seconds\n", elapsed_time);
long long elapsed_time = end_time - start_time;
printf("Time taken : %lld micro seconds\n", elapsed_time);
Tip: enables all compiler warnings.

Related

C find elapsed time in C Linux

I have to calculate the time taken by a function to complete.
This function is called in a loop and I want to find out the total time.
Usually the time is very less in either nano or micro seconds.
To find out the elapsed time I used functions gettimeofday() using struct timeval and clock_gettime() using struct timespec.
Problem is time return by timeval in seconds is correct but in micro seconds wrong.
Similarly the time returned by timespec in nano seconds is wrong.
Wrong in the sense they do not tally with the time returned in seconds.
For clock_gettime() I tried both CLOCK_PROCESS_CPUTIME_ID and CLOCK_MONOTONIC.
Using clock() also does not help.
Code snippet:
struct timeval funcTimestart_timeval, funcTimeEnd_timeval;
struct timespec funcTimeStart_timespec, funcTimeEnd_timespec;
unsigned long elapsed_nanos = 0;
unsigned long elapsed_seconds = 0;
unsigned long diffInNanos = 0;
unsigned long Func_elapsed_nanos = 0;
unsigned long Func_elapsed_seconds = 0;
while(...)
{
gettimeofday(&funcTimestart_timeval, NULL);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &funcTimeStart_timespec);
...
demo_func();
...
gettimeofday(&funcTimeEnd_timeval, NULL);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &funcTimeEnd_timespec);
elapsed_seconds = funcTimeEnd_timeval.tv_sec - funcTimestart_timeval.tv_sec;
Func_elapsed_seconds+= elapsed_seconds;
elapsed_nanos = funcTimeEnd_timespec.tv_nsec - funcTimeStart_timespec.tv_nsec;
Func_elapsed_nanos+ = elapsed_nanos;
}
printf("Total time taken by demo_func() is %lu seconds( %lu nanoseconds )\n", Func_elapsed_seconds, Func_elapsed_nanos );
Printf output:
Total time taken by demo_func() is 60 seconds( 76806787 nanoseconds )
See that the time in seconds and nanoseconds do not match.
How to resolve this issue or any other appropriate method to find elapsed time?
Did you read the documentation of time(7) and clock_gettime(2)? Please read it twice.
The struct timespec is not supposed to express twice the same time. The field tv_sec gives the second part ts, and the field tv_nsec gives the nanosecond part tn to express the time t = ts + 10-9 tn
I would suggest to convert that to a floating point, e.g.
printf ("total time %g\n",
(double)Func_elapsed_seconds + 1.0e-9*Func_elapsed_nanos);
Using floating point is simpler and generally the precision is enough for most needs. Otherwise, when you add or substract struct timespec you need to handle the case when the added/substracted tv_nsec field sum/difference is negative or more than 1000000000....
The problem is you are printing/comparing wrong values.
76,806,787 nanoseconds is equal to ~76 milliseconds, you cannot compare it with 60 seconds.
You are ignoring the time in seconds stored in funcTimeEnd_timespec.tv_sec.
You should also print funcTimeEnd_timespec.tv_sec - funcTimeStart_timespec.tv_sec, and as #Basile Starynkevitch suggested, add with it the nanoseconds part after multiplying it with 10e-9. Then you can compare time elapsed shown by both functions.
I am replying to the previous answers as answer as I wanted to paste code snippets.
Question is to find out elapsed time whether
first I should subtract the corresponding times with each other and then add
(end.tv_sec - start.tv_sec) + 1.0e-9*(end.tv_nsec - start.tv_nsec)
or
first add the times and then compute the difference
(end.tv_sec + 1.0e-9*end.tv_nsec) - (start.tv_sec + 1.0e-9*start.tv_nsec)
In the first case quite often end.tv_nsec is less in number then start.tv_nsec and hence the difference becomes negative number nd this give me wrong number.

timestamp in c with milliseconds precision

I'm relatively new to C programming and I'm working on a project which needs to be very time accurate; therefore I tried to write something to create a timestamp with milliseconds precision.
It seems to work but my question is whether this way is the right way, or is there a much easier way? Here is my code:
#include<stdio.h>
#include<time.h>
void wait(int milliseconds)
{
clock_t start = clock();
while(1) if(clock() - start >= milliseconds) break;
}
int main()
{
time_t now;
clock_t milli;
int waitMillSec = 2800, seconds, milliseconds = 0;
struct tm * ptm;
now = time(NULL);
ptm = gmtime ( &now );
printf("time before: %d:%d:%d:%d\n",ptm->tm_hour,ptm->tm_min,ptm->tm_sec, milliseconds );
/* wait until next full second */
while(now == time(NULL));
milli = clock();
/* DO SOMETHING HERE */
/* for testing wait a user define period */
wait(waitMillSec);
milli = clock() - milli;
/*create timestamp with milliseconds precision */
seconds = milli/CLOCKS_PER_SEC;
milliseconds = milli%CLOCKS_PER_SEC;
now = now + seconds;
ptm = gmtime( &now );
printf("time after: %d:%d:%d:%d\n",ptm->tm_hour,ptm->tm_min,ptm->tm_sec, milliseconds );
return 0;
}
The following code seems likely to provide millisecond granularity:
#include <windows.h>
#include <stdio.h>
int main(void) {
SYSTEMTIME t;
GetSystemTime(&t); // or GetLocalTime(&t)
printf("The system time is: %02d:%02d:%02d.%03d\n",
t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);
return 0;
}
This is based on http://msdn.microsoft.com/en-us/library/windows/desktop/ms724950%28v=vs.85%29.aspx. The above code snippet was tested with CYGWIN on Windows 7.
For Windows 8, there is GetSystemTimePreciseAsFileTime, which "retrieves the current system date and time with the highest possible level of precision (<1us)."
Your original approach would probably be ok 99.99% of the time (ignoring one minor bug, described below). Your approach is:
Wait for the next second to start, by repeatedly calling time() until the value changes.
Save that value from time().
Save the value from clock().
Calculate all subsequent times using the current value of clock() and the two saved values.
Your minor bug was that you had the first two steps reversed.
But even with this fixed, this is not guaranteed to work 100%, because there is no atomicity. Two problems:
Your code loops time() until you are into the next second. But how far are you into it? It could be 1/2 a second, or even several seconds (e.g. if you are running a debugger with a breakpoint).
Then you call clock(). But this saved value has to 'match' the saved value of time(). If these two calls are almost instantaneous, as they usually are, then this is fine. But Windows (and Linux) time-slice, and so there is no guarantee.
Another issue is the granularity of clock. If CLOCKS_PER_SEC is 1000, as seems to be the case on your system, then of course the best you can do is 1 msec. But it can be worse than that: on Unix systems it is typically 15 msecs. You could improve this by replacing clock with QueryPerformanceCounter(), as in the answer to timespec equivalent for windows, but this may be otiose, given the first two problems.
Clock periods are not at all guaranteed to be in milliseconds. You need to explicitly convert the output of clock() to milliseconds.
t1 = clock();
// do something
t2 = clock();
long millis = (t2 - t1) * (1000.0 / CLOCKS_PER_SEC);
Since you are on Windows, why don't you just use Sleep()?

Measuring elapsed time in linux for a c program

I am trying to measure elapsed time in Linux. My answer keeps returning zero which makes no sense to me. Below is the way i 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);
}
Three alternatives
clock()
gettimeofday()
clock_gettime()
clock_gettime() goes upto nanosecond accuracy and it supports 4 clocks.
CLOCK_REALTIME
System-wide realtime clock. Setting this clock requires appropriate privileges.
CLOCK_MONOTONIC
Clock that cannot be set and represents monotonic time since some unspecified starting point.
CLOCK_PROCESS_CPUTIME_ID
High-resolution per-process timer from the CPU.
CLOCK_THREAD_CPUTIME_ID
Thread-specific CPU-time clock.
You can use it as
#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
Note: The clock() function returns CPU time for your process, not wall clock time. I believe this is what the OP was interested in. If wall clock time is desired, then gettimeofday() is a good choice as suggested by an earlier answer. clock_gettime() can do either one if your system supports it; on my linux embedded system clock_gettime() is not supported, but clock() and gettimeofday() are.
Below is the code for getting wall clock time 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;
}
To start with you need to use floating point arithmetics. Any integer value divided by a larger integer value will be zero, always.
And of course you should actually do something between getting the start and end times.
By the way, if you have access to gettimeofday it's normally preferred over clock as it has higher resolution. Or maybe clock_gettime which has even higher resolution.
There are two issues with your code as written.
According to man 3 clock, the resolution of clock() is in CLOCKS_PER_SEC increments per second. On a recent-ish Cygwin system, it's 200. Based on the names of your variables, you are expecting the value to be 1,000,000.
This line:
millis = micros / 1000;
will compute the quotient as an integer, because both operands are integers. The promotion to a floating-point type occurs at the time of the assignment to millis, at which point the fractional part has already been discarded.
To compute 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 will almost certainly not get millisecond accuracy. For that, you would need to use gettimeofday() or clock_gettime(). Further, you probably want to use double instead of float, because you are likely going to wind up subtracting very large numbers with a very tiny difference. The example using clock_gettime() would be:
#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_nsec / 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, the division operations are carried out in floating-point.
Sources:
man pages for clock(3), gettimeofday(3), and clock_gettime(3).
The C Programming Language, Kernighan and Ritchie
Try Sunil D S's answer but change micros from unsigned long to type float or double, like this:
double micros;
float seconds;
clock_t start, end;
start = clock();
/* Do something here */
end = clock();
micros = end - start;
seconds = micros / 1000000;
Alternatively, you could use rusage, like this:
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);
Units and precision depend on how much time you want to measure but either of these should
provide reasonable accuracy for ms.
When you divide, you might end up with a decimal, hence you need a flaoting point number to store the number of milli seconds.
If you don't use a floating point, the decimal part is truncated. In your piece of code, the start and end are ALMOST the same. Hence the result after division when stored in a 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;

Time in milliseconds in C

Using the following code:
#include<stdio.h>
#include<time.h>
int main()
{
clock_t start, stop;
int i;
start = clock();
for(i=0; i<2000;i++)
{
printf("%d", (i*1)+(1^4));
}
printf("\n\n");
stop = clock();
//(double)(stop - start) / CLOCKS_PER_SEC
printf("%6.3f", start);
printf("\n\n%6.3f", stop);
return 0;
}
I get the following output:
56789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004
2.169
2.169
Start and stop times are the same. Does it mean that the program hardly takes time to complete execution?
If 1. is false, then atleast the no.of digits beyond the (.) should differ, which does not happen here. Is my logic correct?
Note: I need to calculate the time taken for execution, and hence the above code.
Yes, this program has likely used less than a millsecond. Try using microsecond resolution with timeval.
e.g:
#include <sys/time.h>
struct timeval stop, start;
gettimeofday(&start, NULL);
//do stuff
gettimeofday(&stop, NULL);
printf("took %lu us\n", (stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec - start.tv_usec);
You can then query the difference (in microseconds) between stop.tv_usec - start.tv_usec. Note that this will only work for subsecond times (as tv_usec will loop). For the general case use a combination of tv_sec and tv_usec.
Edit 2016-08-19
A more appropriate approach on system with clock_gettime support would be:
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
//do stuff
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
Here is what I write to get the timestamp in millionseconds.
#include<sys/time.h>
long long timeInMilliseconds(void) {
struct timeval tv;
gettimeofday(&tv,NULL);
return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000);
}
A couple of things might affect the results you're seeing:
You're treating clock_t as a floating-point type, I don't think it is.
You might be expecting (1^4) to do something else than compute the bitwise XOR of 1 and 4., i.e. it's 5.
Since the XOR is of constants, it's probably folded by the compiler, meaning it doesn't add a lot of work at runtime.
Since the output is buffered (it's just formatting the string and writing it to memory), it completes very quickly indeed.
You're not specifying how fast your machine is, but it's not unreasonable for this to run very quickly on modern hardware, no.
If you have it, try adding a call to sleep() between the start/stop snapshots. Note that sleep() is POSIX though, not standard C.
This code snippet can be used for displaying time in seconds,milliseconds and microseconds:
#include <sys/time.h>
struct timeval start, stop;
double secs = 0;
gettimeofday(&start, NULL);
// Do stuff here
gettimeofday(&stop, NULL);
secs = (double)(stop.tv_usec - start.tv_usec) / 1000000 + (double)(stop.tv_sec - start.tv_sec);
printf("time taken %f\n",secs);
You can use gettimeofday() together with the timedifference_msec() function below to calculate the number of milliseconds elapsed between two samples:
#include <sys/time.h>
#include <stdio.h>
float timedifference_msec(struct timeval t0, struct timeval t1)
{
return (t1.tv_sec - t0.tv_sec) * 1000.0f + (t1.tv_usec - t0.tv_usec) / 1000.0f;
}
int main(void)
{
struct timeval t0;
struct timeval t1;
float elapsed;
gettimeofday(&t0, 0);
/* ... YOUR CODE HERE ... */
gettimeofday(&t1, 0);
elapsed = timedifference_msec(t0, t1);
printf("Code executed in %f milliseconds.\n", elapsed);
return 0;
}
Note that, when using gettimeofday(), you need to take seconds into account even if you only care about microsecond differences because tv_usec will wrap back to zero every second and you have no way of knowing beforehand at which point within a second each sample is obtained.
From man clock:
The clock() function returns an approximation of processor time used by the program.
So there is no indication you should treat it as milliseconds. Some standards require precise value of CLOCKS_PER_SEC, so you could rely on it, but I don't think it is advisable.
Second thing is that, as #unwind stated, it is not float/double. Man times suggests that will be an int.
Also note that:
this function will return the same value approximately every 72 minutes
And if you are unlucky you might hit the moment it is just about to start counting from zero, thus getting negative or huge value (depending on whether you store the result as signed or unsigned value).
This:
printf("\n\n%6.3f", stop);
Will most probably print garbage as treating any int as float is really not defined behaviour (and I think this is where most of your problem comes). If you want to make sure you can always do:
printf("\n\n%6.3f", (double) stop);
Though I would rather go for printing it as long long int at first:
printf("\n\n%lldf", (long long int) stop);
The standard C library provides timespec_get. It can tell time up to nanosecond precision, if the system supports. Calling it, however, takes a bit more effort because it involves a struct. Here's a function that just converts the struct to a simple 64-bit integer so you can get time in milliseconds.
#include <stdio.h>
#include <inttypes.h>
#include <time.h>
int64_t millis()
{
struct timespec now;
timespec_get(&now, TIME_UTC);
return ((int64_t) now.tv_sec) * 1000 + ((int64_t) now.tv_nsec) / 1000000;
}
int main(void)
{
printf("Unix timestamp with millisecond precision: %" PRId64 "\n", millis());
}
Unlike clock, this function returns a Unix timestamp so it will correctly account for the time spent in blocking functions, such as sleep.
Modern processors are too fast to register the running time. Hence it may return zero. In this case, the time you started and ended is too small and therefore both the times are the same after round of.

elapsed time in negative value

struct timeval start, end;
start.tv_usec = 0;
end.tv_usec = 0;
gettimeofday(&start, NULL);
functionA();
gettimeofday(&end, NULL);
long t = end.tv_usec - start.tv_usec;
printf("Total elapsed time %ld us \n", t);
I am calculating the total elapsed time like this but it sometimes shows a negative value.
What might be cause the problem?
Thanks in advance.
Keep in mind that there is both a seconds and micro-seconds field of that structure. Therefore if you are simply subtracting the micro-seconds field, you could have a time that is later in seconds, but the microseconds field is less. For instance, and end-time of 5 seconds, 100 microseconds will have a negative result compared to 4 seconds and 5000 microseconds with the subtraction method you're using. In order to get the proper result, you have to take into account both the seconds and micro-seconds fields of the structure. This can be done doing the following:
long seconds = end.tv_sec - start.tv_sec;
long micro_seconds = end.tv_usec - start.tv_usec;
if (micro_seconds < 0)
{
seconds -= 1;
}
long total_micro_seconds = (seconds * 1000000) + abs(micro_seconds);
maybe something along the lines of:
long t = (end.tv_sec*1e6 + end.tv_usec) - (start.tv_sec*1e6 + start.tv_usec);
From The GNU C Library:
Data Type: struct timeval
The struct timeval structure represents an elapsed time. It is declared in sys/time.h and has the following members:
long int tv_sec
This represents the number of whole seconds of elapsed time.
long int tv_usec
This is the rest of the elapsed time (a fraction of a second), represented as the number of microseconds. It is always less than one million.
The only thing you're subtracting is the microseconds in tv_usec above the full seconds value in tv_sec. You need to work with both values in order to find the exact microsecond difference between the two times.

Resources