corsel
corsel

Reputation: 325

<time.h> clock() does not work properly

I was trying to estimate the duration of a code block (particularly to get the time step of a physics-based animation for frame rate indepedency, so resolution should be in milliseconds grade). Questions here at stack overflow mostly recommend clock() method, I have tried it but it does not seem to work properly. I have solved the problem using gettimeoftheday() method, but still I'm curious as to why clock() fails. Here's my code block:

for (int i = 0; i < 10000; i++)
{
    std::cout << "time: " << clock() << std::endl;
    usleep(1000);
}

This prints time at a rate. When I increase the usleep value to, say 1000000, the increase rate of printed clock values drastically drop. I thought clock() should give a value related to an absolute time value, independent of my code.

Thanks in advance.

PS: To get a possible misunderstanding out of the way in advance, I'm not complaining the printing ratio has dropped. The VALUE printed at a certain delta time is not the same between usleep(1000) and usleep(1000000).

Upvotes: 0

Views: 1422

Answers (2)

hdante
hdante

Reputation: 8020

The question assumptions are wrong but I had to upvote the question because time measurement and time APIs are confusing, so the user is right to ask such question.

  • there are "real time clocks", which tries to track what time is it in "calendar time", that is, time people use. These can go forward 1 hour, backward 1 hour, forward 1 second, etc. These must never be used to measure the length of a computation. So time(), gettimeofday() and clock_gettime(CLOCK_REALTIME) are out.
  • there are "monotonic clocks", which tries to track real time passing, in a coordinated way with other people. These clocks never go back in time and unlike "real time clocks" are usable clocks for measuring performance. They can still be adjusted on the fly, like slowed down or sped up for 1 second to synchronize with other people, however. They are very portable, for example, by using clock_gettime(CLOCK_MONOTONIC).
  • there are the "raw clocks", which tries to track real time passing without coordinating with other people. Linux has clock_gettime(CLOCK_MONOTONIC_RAW), which simply uses the hardware clock to count. Those are really good to measure time spent on a procedure, as long as you want to include time spent sleeping or waiting for I/O. On medium and long terms they can't be used to coordinate time with other people, due to the hardware clock drift and oscillation.
  • there are the "cpu clocks", which tries to track cpu usage time. They may include user code time, kernel time, but don't include time where the process is sleeping. clock_gettime(CLOCK_PROCESS_CPUTIME_ID), times() and clock() return these.
  • finally, there are "timers", which use the above clocks to implement repeatable timed signals with more or less precise intervals. Those are things like timer_create(), timerfd_create() and setitimer().

Given the problem description, I would use the last ones for the calculation: set a 1 second interval timer that triggers a signal when done. Then print the number of frames you were able to draw. You can adjust frame rendering complexity with this number later.

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254461

I thought clock() should give a value related to an absolute time value

You thought wrong. From its specification (C99 7.32.2.1)

The clock function determines the processor time used.

Use time, or a suitable clock from the std::chrono library, or something less portable like clock_gettime or gettimeofday, if you want absolute time.

Upvotes: 1

Related Questions