5

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?

underdoeg
  • 1,713
  • 3
  • 13
  • 23
  • aah, wait a minute. so CLOCK_PROCESS_CPUTIME_ID should only return the elapsed time where actual CPU power was used? – underdoeg Aug 10 '12 at 11:49
  • Right, it measures only CPU time. – Daniel Fischer Aug 10 '12 at 11:51
  • and if so, what should I use CLOCK_REALTIME? Is that really precise? I don't need nano seconds, but as accurate microseconds as possible... – underdoeg Aug 10 '12 at 11:51
  • What is it that you want to measure? `CLOCK_MONOTONIC` may be interesting for you. – Daniel Fischer Aug 10 '12 at 11:52
  • we're working on a class to have precise timing for video playback and similar things. https://github.com/obviousjim/ofxMSATimer/blob/develop/src/ofxMSATimer.cpp Basically all we need is to precisely get the current running time of the application in microseconds. – underdoeg Aug 10 '12 at 11:54

1 Answers1

6

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, &current)) {
        /* 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;
}
Daniel Fischer
  • 174,737
  • 16
  • 293
  • 422
  • would you recommend removing the rounding up, and display it in double format? – aah134 Sep 13 '13 at 16:12
  • Whichever format one prefers. One should be aware that although the resolution may be (typically is, nowadays) one nanosecond, the accuracy of the clock usually is coarser 10-100 nanoseconds, possibly even more. So at some point, the digits become meaningless. – Daniel Fischer Sep 13 '13 at 17:32