I'm doing a algorithm project for my University. In the project I have to write some algorithms and evaluate their time using a monotonic clock.
I've already implemented everything using C but now I'm facing problems with the time measuring.
I'm currently using clock_gettime(CLOCK_MONOTONIC_RAW, ...)
to get a clock. From the manpage of clock_gettime
:
CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
Similar to CLOCK_MONOTONIC, but provides access to a raw hardware-based time that is not subject to NTP adjustments
or the incremental adjustments performed by adjtime(3). This clock does not count time that the system is sus‐
pended.
The problem is the following: this clock sometimes returns a negative value when a measure like this is done:
struct timespec start,end;
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
do{
// do stuff in here
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
} while((double) (end.tv_nsec - start.tv_nsec) <= *a certain quantity needed for precision*);
In particular, sometimes end.tv_nsec - start.tv_nsec
is negative and this causes the program to loop into this do-while.
As this should be a monotonic clock (which never goes back), things like having a negative elapsed time should not happen. But still, it seems to be happening.
Is this clock really monotonic? Am i doing something wrong? What can I try to figure out what is wrong?
I am really lost, I've tried lot of things in the past few days and none has worked out. In the case that more code is needed, see my repo: https://github.com/AlessandroZanatta/AlgorithmsProject/blob/dev/first_part/times.c
Look at man timespec
There is written:
struct timespec { time_t tv_sec; long tv_nsec; };
The tv_sec member is again the elapsed time in whole seconds. The tv_nsec member represents the rest of the elapsed time in nanoseconds.
So tv_nsec
is just the rest of the time not representable in whole seconds, so you need to subtract seconds and nanoseconds.
Also here https://ftp.gnu.org/old-gnu/Manuals/glibc-2.2.5/html_node/Elapsed-Time.html is presented "the best way" to subtract two values of type struct timeval
, as follows:
(For struct timespec
just substitute timespec
for timeval
, tv_nsec
for tv_usec
and 1000000000
for 1000000
.)
It is often necessary to subtract two values of type struct timeval or struct timespec. Here is the best way to do this. It works even on some peculiar operating systems where the tv_sec member has an unsigned type.
/* Subtract the `struct timeval' values X and Y, storing the result in RESULT. Return 1 if the difference is negative, otherwise 0. */ int timeval_subtract (result, x, y) struct timeval *result, *x, *y; { /* Perform the carry for the later subtraction by updating y. */ if (x->tv_usec < y->tv_usec) { int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; y->tv_usec -= 1000000 * nsec; y->tv_sec += nsec; } if (x->tv_usec - y->tv_usec > 1000000) { int nsec = (x->tv_usec - y->tv_usec) / 1000000; y->tv_usec += 1000000 * nsec; y->tv_sec -= nsec; } /* Compute the time remaining to wait. tv_usec is certainly positive. */ result->tv_sec = x->tv_sec - y->tv_sec; result->tv_usec = x->tv_usec - y->tv_usec; /* Return 1 if result is negative. */ return x->tv_sec < y->tv_sec; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With