I'm on a 64bit Ubuntu 12.04 system and tried the following code:
#include <unistd.h>
#include <time.h>
#include <stdio.h>
int
main(void)
{
struct timespec user1,user2;
struct timespec sys1,sys2;
double user_elapsed;
double sys_elapsed;
clock_gettime(CLOCK_REALTIME, &user1);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &sys1);
sleep(10);
clock_gettime(CLOCK_REALTIME, &user2);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &sys2);
user_elapsed = user2.tv_sec + user2.tv_nsec/1E9;
user_elapsed -= user1.tv_sec + user1.tv_nsec/1E9;
printf("CLOCK_REALTIME: %f\n", user_elapsed);
sys_elapsed = sys2.tv_sec + sys2.tv_nsec/1E9;
sys_elapsed -= sys1.tv_sec + sys1.tv_nsec/1E9;
printf("CLOCK_PROCESS_CPUTIME_ID: %f\n", sys_elapsed);
}
As I understand it, this should print something like
CLOCK_REALTIME: 10.000117
CLOCK_PROCESS_CPUTIME_ID: 10.001
But in my case, what I get is
CLOCK_REALTIME: 10.000117
CLOCK_PROCESS_CPUTIME_ID: 0.000032
Is this the correct behaviour? If so how I can I determine the actual seconds of sys1 and sys2?
When I change CLOCK_PROCESS_CPUTIME_ID to CLOCK_REALTIME then I get the expected result, but that's not what I want because we need the precision.
[EDIT] Apparently CLOCK_PROCESS_CPUTIME_ID returns the actual time the cpu spent on prcessing. CLOCK_MONOTONIC seems to return the right value. But at what precision?
Basically all we need is to precisely get the current running time of the application in microseconds.
Running time here means elapsed time, if I don't misunderstand. Normally, CLOCK_REALTIME
is good for that, but if the time is set during the run of the application, CLOCK_REALTIME
's notion of elapsed time changes too. To prevent that - unlikely as it may be - I suggest using CLOCK_MONOTONIC
or, if present, CLOCK_MONOTONIC_RAW
. From the description in the man page
CLOCK_REALTIME
System-wide real-time clock. Setting this clock requires appro-
priate privileges.
CLOCK_MONOTONIC
Clock that cannot be set and represents monotonic time since
some unspecified starting point.
CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
Similar to CLOCK_MONOTONIC, but provides access to a raw hard-
ware-based time that is not subject to NTP adjustments.
CLOCK_MONOTONIC
may be influenced by NTP adjustments, while CLOCK_MONOTONIC_RAW
isn't. All these clocks typically have a resolution of one nanosecond (check that with clock_getres()
), but for your purposes a resolution below one microsecond would suffice.
To calculate elapsed time in microseconds
#define USED_CLOCK CLOCK_MONOTONIC // CLOCK_MONOTONIC_RAW if available
#define NANOS 1000000000LL
int main(int argc, char *argv[]) {
/* Whatever */
struct timespec begin, current;
long long start, elapsed, microseconds;
/* set up start time data */
if (clock_gettime(USED_CLOCK, &begin)) {
/* Oops, getting clock time failed */
exit(EXIT_FAILURE);
}
/* Start time in nanoseconds */
start = begin.tv_sec*NANOS + begin.tv_nsec;
/* Do something interesting */
/* get elapsed time */
if (clock_gettime(USED_CLOCK, ¤t)) {
/* getting clock time failed, what now? */
exit(EXIT_FAILURE);
}
/* Elapsed time in nanoseconds */
elapsed = current.tv_sec*NANOS + current.tv_nsec - start;
microseconds = elapsed / 1000 + (elapsed % 1000 >= 500); // round up halves
/* Display time in microseconds or something */
return EXIT_SUCCESS;
}