62

I've always used clock() to measure how much time my application took from start to finish, as;

int main(int argc, char *argv[]) {
  const clock_t START = clock();

  // ...

  const double T_ELAPSED = (double)(clock() - START) / CLOCKS_PER_SEC;
}

Since I've started using POSIX threads this seem to fail. It looks like clock() increases N times faster with N threads. As I don't know how many threads are going to be running simultaneously, this approach fails. So how can I measure how much time has passed ?

Suugaku
  • 2,667
  • 5
  • 31
  • 33
  • 1
    See [Is gettimeofday() guaranteed to be of microsecond resolution?](http://stackoverflow.com/questions/88/is-gettimeofday-guaranteed-to-be-of-microsecond-resolution) – Matthew Flaschen Jun 03 '10 at 01:25
  • See this answer for a portable solution: http://stackoverflow.com/questions/361363/how-to-measure-time-in-milliseconds-using-ansi-c/37920181#37920181 – Alexander Saprykin Jun 27 '16 at 13:56

2 Answers2

129

clock() measure the CPU time used by your process, not the wall-clock time. When you have multiple threads running simultaneously, you can obviously burn through CPU time much faster.

If you want to know the wall-clock execution time, you need to use an appropriate function. The only one in ANSI C is time(), which typically only has 1 second resolution.

However, as you've said you're using POSIX, that means you can use clock_gettime(), defined in time.h. The CLOCK_MONOTONIC clock in particular is the best to use for this:

struct timespec start, finish;
double elapsed;

clock_gettime(CLOCK_MONOTONIC, &start);

/* ... */

clock_gettime(CLOCK_MONOTONIC, &finish);

elapsed = (finish.tv_sec - start.tv_sec);
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;

(Note that I have done the calculation of elapsed carefully to ensure that precision is not lost when timing very short intervals).

If your OS doesn't provide CLOCK_MONOTONIC (which you can check at runtime with sysconf(_SC_MONOTONIC_CLOCK)), then you can use CLOCK_REALTIME as a fallback - but note that the latter has the disadvantage that it will generate incorrect results if the system time is changed while your process is running.

Conchylicultor
  • 4,631
  • 2
  • 37
  • 40
caf
  • 233,326
  • 40
  • 323
  • 462
  • 3
    >> This is the correct answer as posted by @caf in the ocean of many misleading answers on SO. This is especially correct for realtime systems that do support POSIX. I would NOT use clock, time, gettimeofday or any other function for this purpose. < – Xofo May 25 '16 at 18:45
  • What do you mean by "carefully" calculating `elapsed`? Is there some significance to using two separate statements instead of combining them into one assignment? – sevko Dec 04 '16 at 17:47
  • 2
    @sevko: No, it could be done in one statement - what I'm referring to there is subtracting both 'seconds' portions separately from both 'nanoseconds' portions, rather than (for example) converting 'finish' and 'start' to floating point values first and then subtracting them. – caf Dec 04 '16 at 23:04
  • While this works if no thread is sleeping, it fails to measure remaining CPU time after each frame. – user877329 Mar 21 '17 at 10:33
  • Missing namespace? identifier "clock_gettime" is undefined. also for CLOCK_MONOTONIC – Pedro77 Apr 23 '17 at 15:24
  • @Pedro77: [POSIX requires](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html) that `` declares `clock_gettime()` and `CLOCK_MONOTONIC`. – caf Apr 24 '17 at 01:40
  • Note that your 'elapsed' calculation is only correct when `tv_nsec` is signed. This is true of Posix, but may not be so on other systems. If it's unsigned, the result will be (very) wrong on half of all measurements. – EML Dec 13 '22 at 18:52
  • @EML: The C standard requires `tv_nsec` to be of type `long`. – caf Dec 15 '22 at 03:30
  • Only since C11, after your answer. MS, at least, didn't claim C11 compliance till 2020, and still doesn't claim full compliance. Given that a lot of people who want to do this sort of measurement will be on embedded systems, it would make sense for them to check first. – EML Dec 15 '22 at 13:17
  • @EML: Yes, and if they're not on a POSIX system they should also check that `clock_gettime()` works similarly as well. – caf Dec 16 '22 at 01:01
1

What timing resolution do you need? You could use time() from time.h for second resolution. If you need higher resolution, then you could use something more system specific. See Timer function to provide time in nano seconds using C++

Community
  • 1
  • 1
Manfre
  • 1,235
  • 10
  • 10