为什么 clock() 被认为是坏的?

Why is clock() considered bad?

我曾经被建议使用依赖于平台的方法(GetTickCount() for Windows)来获取时间而不是使用 clock(),因为它不好或不可靠。为什么?还有很多人建议的 <chrono> header 函数,但是,我在 IDE (VS 2010) 中找不到它。

我的目标是游戏开发,如果重要的话。

根据: 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. "

还有:

"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. "

希望对您有所帮助。

这并不是说时钟一定被认为是坏的,因为它没有被定义为按照人们通常认为的方式运行。即,未指定生成挂钟或 'real'、时间。

clock()定义告诉你用了多少CPU时间;使用更多线程使用更多 CPU 时间,休眠线程使用更少时间。

其次,并非所有平台都实现相同的行为;一些平台实现 clock() 就好像它应该给出挂钟时间一样。因此可移植代码不能将其用于任何目的。


然而,即使对于非便携式用途,clock() 可能被认为不好的一个原因是它有一个 'type-unsafe' API,它不区分时间点和持续时间,并且不能为您安全地管理时间单位。例如,使用它的 API 可能很容易将应该表示微秒的值与表示毫秒的值混合在一起。

C++11 <chrono> API 在这些方面做得更好。一个问题是 <chrono> 没有 CPU 时钟。如果你想要挂钟时间,那么 std::chrono::steady_clock 是最好的选择;它有一个类型安全的 API 并且被定义为前进 '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.


为了好玩,这里有一个 <chrono> 风格的时钟,用于使用 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()}};
    }
};