Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is clock() considered bad?

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.

like image 928
Pilpel Avatar asked Feb 08 '15 15:02

Pilpel


People also ask

How accurate is clock in C?

It has nanosecond precision.

What is the clock function in C++?

The clock() function in C++ returns the approximate processor time that is consumed by the program. In order to compute the processor time, the difference between values returned by two different calls to clock(), one at the start and other at the end of the program is used.


Video Answer


2 Answers

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()}};
    }
};
like image 129
bames53 Avatar answered Sep 21 '22 08:09

bames53


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.

like image 29
Galik Avatar answered Sep 20 '22 08:09

Galik