15

I was once advised to use a platform dependent method (GetTickCount() for Windows) for getting time instead of using clock(), because it's bad or unreliable. Why? There's also this <chrono> header functions that many suggest, however, I can't find it in my IDE (VS 2010).

My target is game development, if it matters.

McLovin
  • 3,295
  • 7
  • 32
  • 67

2 Answers2

21

It's not that clock is considered bad, necessarily, so much as it's not defined to operate the way people often think it is. Namely, it's not specified to produce wall-clock, or 'real', time.

clock() is defined to tell you how much CPU time is used; using more threads uses more CPU time, sleeping threads use less time.

Secondly, not all platforms implement the same behavior; some platforms implement clock() as though it were supposed to give wall-clock time. Thus portable code can't use it for either purpose.


However, one reason clock() might be considered bad, even for non-portable uses, is that it has a 'type-unsafe' API which doesn't distinguish between time points and time durations, and which does not safely manage units of time for you. For example, using its API one might easily mix values that are supposed to represent microseconds with values meant to represent milliseconds.

The C++11 <chrono> API is much better about these things. The one problem is that <chrono> doesn't have a CPU time clock. If you want wall-clock time then std::chrono::steady_clock is the best choice; It has a type-safe API and it's defined to advance 'at a steady rate with real time'.


http://coliru.stacked-crooked.com/a/6df6c71a436092e3

Sleeping 4 threads for 0.1 seconds each.
Elapsed wall time: 0.101213 seconds.
Elapsed cpu time: 0 seconds.
Spinning 4 threads for 0.1 seconds each.
Elapsed wall time: 0.100304 seconds.
Elapsed cpu time: 0.4 seconds.


And for fun here's a <chrono> style clock for using std::clock():

#include <chrono>
#include <ratio>
#include <ctime>

struct cpu_clock {
    using rep = std::clock_t;
    using period = std::ratio<1, CLOCKS_PER_SEC>;
    using duration = std::chrono::duration<rep, period>;
    using time_point = std::chrono::time_point<cpu_clock, duration>;

    static const bool is_steady = false;

    static time_point now() noexcept {
        return time_point{duration{std::clock()}};
    }
};
bames53
  • 86,085
  • 15
  • 179
  • 244
  • 1
    What do you mean by "wall-clock time"? – McLovin Feb 08 '15 at 18:33
  • 1
    Consider the following code: `void func(void *x) { while(true) {} } void main() { _beginthread(func, 0, 0); while(true) cout << clock() << endl; }` CPU time should be increasing twice the normal speed, but it doesn't. Why? – McLovin Feb 08 '15 at 18:59
  • @Pilpel The most obvious answer is that you code is obviously Windows, and `clock` in Visual Studios is broken. – James Kanze Feb 08 '15 at 19:23
  • @JamesKanze So VS compiler interprets clock() wrong? – McLovin Feb 08 '15 at 19:29
  • @Pilpel Yes, Microsoft's implementation of clock() measures wall-clock time instead of CPU time. (And wall-clock time refers to the quantity that a literal clock on the wall measures.) – bames53 Feb 08 '15 at 19:46
  • 5
    @Pilpel "wall-clock time" is exactly that: time as measured by the clock hanging on your wall. – Martin Tournoij Feb 08 '15 at 21:44
  • @Pilpel There implementation is not what the C standard specifies. – James Kanze Feb 08 '15 at 22:43
  • @Carpetsmoker which is not the same as monotonic time, and does not steadily increase. – user253751 Feb 08 '15 at 23:11
  • 1
    @immibis actually the term wall-clock time does typically mean monotonic time; while timing a task using a wall-clock you don't typically reset the clock. wall-clock time contrasts with what we might call 'calendar' time or system time, which just represents the 'current' time under popular time keeping schemes and which does get adjusted for various reasons, and which is therefore not much use in accurately timing durations. `chrono::steady_clock` will allow you to determine wall-clock durations, and `chrono::system_clock` will (probably) give you 'calendar' time. – bames53 Feb 09 '15 at 01:28
9

According to: cppreference.com: std::clock().

"std::clock time may advance faster or slower than the wall clock, depending on the execution resources given to the program by the operating system. For example, if the CPU is shared by other processes, std::clock time may advance slower than wall clock. On the other hand, if the current process is multithreaded and more than one execution core is available, std::clock time may advance faster than wall clock. "

Also:

"The value returned by clock() may wrap around on some implementations. For example, on a machine with 32-bit std::clock_t, it wraps after 2147 seconds or 36 minutes. "

Hope this helps.

Galik
  • 47,303
  • 4
  • 80
  • 117