简体   繁体   English

std::system_clock 和 std::steady_clock 之间的区别?

[英]Difference between std::system_clock and std::steady_clock?

What is the difference between std::system_clock and std::steady_clock ? std::system_clockstd::steady_clock什么区别? (An example case that illustrate different results/behaviours would be great). (说明不同结果/行为的示例案例会很棒)。

If my goal is to precisely measure execution time of functions (like a benchmark), what would be the best choice between std::system_clock , std::steady_clock and std::high_resolution_clock ?如果我的目标是精确测量函数的执行时间(如基准测试),那么std::system_clockstd::steady_clockstd::high_resolution_clock ::high_resolution_clock 之间的最佳选择是什么?

From N3376:来自 N3376:

20.11.7.1 [time.clock.system]/1: 20.11.7.1 [时间.时钟.系统]/1:

Objects of class system_clock represent wall clock time from the system-wide realtime clock. system_clock类的对象表示来自系统范围实时时钟的挂钟时间。

20.11.7.2 [time.clock.steady]/1: 20.11.7.2 [time.clock.steady]/1:

Objects of class steady_clock represent clocks for which values of time_point never decrease as physical time advances and for which values of time_point advance at a steady rate relative to real time. steady_clock类的对象表示time_point的值从不随着物理时间的增加而减少的时钟,并且time_point的值相对于实时以稳定的速率增加。 That is, the clock may not be adjusted.也就是说,可以不调整时钟。

20.11.7.3 [time.clock.hires]/1: 20.11.7.3 [time.clock.hires]/1:

Objects of class high_resolution_clock represent clocks with the shortest tick period. high_resolution_clock类的对象表示具有最短滴答周期的时钟。 high_resolution_clock may be a synonym for system_clock or steady_clock . high_resolution_clock可能是system_clocksteady_clock的同义词。

For instance, the system wide clock might be affected by something like daylight savings time, at which point the actual time listed at some point in the future can actually be a time in the past.例如,系统范围的时钟可能会受到夏令时之类的影响,此时在未来某个时间点列出的实际时间实际上可能是过去的时间。 (Eg in the US, in the fall time moves back one hour, so the same hour is experienced "twice") However, steady_clock is not allowed to be affected by such things. (例如,在美国,秋天的时间会倒退一个小时,因此同一小时经历“两次”)但是,不允许steady_clock受此类影响。

Another way of thinking about "steady" in this case is in the requirements defined in the table of 20.11.3 [time.clock.req]/2:在这种情况下,另一种思考“稳定”的方式是在 20.11.3 [time.clock.req]/2 的表中定义的要求:

In Table 59 C1 and C2 denote clock types.在表 59 中, C1C2表示时钟类型。 t1 and t2 are values returned by C1::now() where the call returning t1 happens before the call returning t2 and both of these calls occur before C1::time_point::max() . t1t2是由C1::now()返回的值,其中返回t1的调用发生在返回t2的调用之前,并且这两个调用都发生在C1::time_point::max()之前。 [ Note: this means C1 did not wrap around between t1 and t2 . [ 注意:这意味着C1没有在t1t2之间回绕。 —end note ] ——尾注]

Expression: C1::is_steady表达式: C1::is_steady
Returns: const bool返回值: const bool
Operational Semantics: true if t1 <= t2 is always true and the time between clock ticks is constant, otherwise false .操作语义: true t1 <= t2始终为 true 并且时钟滴答之间的时间是恒定的,则为 true ,否则为false

That's all the standard has on their differences.这就是标准对它们的区别的全部。

If you want to do benchmarking, your best bet is probably going to be std::high_resolution_clock , because it is likely that your platform uses a high resolution timer (eg QueryPerformanceCounter on Windows) for this clock.如果您想进行基准测试,最好的选择可能是std::high_resolution_clock ,因为您的平台很可能为此时钟使用高分辨率计时器(例如 Windows 上的QueryPerformanceCounter )。 However, if you're benchmarking, you should really consider using platform specific timers for your benchmark, because different platforms handle this differently.但是,如果您要进行基准测试,您真的应该考虑为您的基准测试使用平台特定的计时器,因为不同的平台处理方式不同。 For instance, some platforms might give you some means of determining the actual number of clock ticks the program required (independent of other processes running on the same CPU).例如,某些平台可能会为您提供一些方法来确定程序所需的实际时钟滴答数(独立于同一 CPU 上运行的其他进程)。 Better yet, get your hands on a real profiler and use that.更好的是,得到一个真正的分析器并使用它。

Billy provided a great answer based on the ISO C++ standard that I fully agree with. Billy 根据我完全同意的 ISO C++ 标准提供了一个很好的答案。 However there is another side of the story - real life.然而,故事还有另一面——现实生活。 It seems that right now there is really no difference between those clocks in implementation of popular compilers:现在看来,在流行编译器的实现中,这些时钟之间确实没有区别:

gcc 4.8:海合会 4.8:

#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
   ...
#else
  typedef system_clock steady_clock;
#endif
  typedef system_clock high_resolution_clock;

Visual Studio 2012:视觉工作室 2012:

class steady_clock : public system_clock
{   // wraps monotonic clock
public:
  static const bool is_monotonic = true;    // retained
  static const bool is_steady = true;
};

typedef system_clock high_resolution_clock;

In case of gcc you can check if you deal with steady clock simply by checking is_steady and behave accordingly.在 gcc 的情况下,您可以通过检查is_steady来检查是否处理稳定时钟并相应地进行操作。 However VS2012 seems to cheat a bit here:-)然而 VS2012 似乎在这里有点作弊:-)

If you need high precision clock I recommend for now writing your own clock that conforms to C++11 official clock interface and wait for implementations to catch up.如果您需要高精度时钟,我建议您现在编写自己的符合 C++11 官方时钟接口的时钟,并等待实现赶上。 It will be much better approach than using OS specific API directly in your code.这比直接在您的代码中使用特定于操作系统的 API 要好得多。 For Windows you can do it like that:对于 Windows,您可以这样做:

// Self-made Windows QueryPerformanceCounter based C++11 API compatible clock
struct qpc_clock {
  typedef std::chrono::nanoseconds                       duration;      // nanoseconds resolution
  typedef duration::rep                                  rep;
  typedef duration::period                               period;
  typedef std::chrono::time_point<qpc_clock, duration>   time_point;
  static bool is_steady;                                                // = true
  static time_point now()
  {
    if(!is_inited) {
      init();
      is_inited = true;
    }
    LARGE_INTEGER counter;
    QueryPerformanceCounter(&counter);
    return time_point(duration(static_cast<rep>((double)counter.QuadPart / frequency.QuadPart *
                                                period::den / period::num)));
  }

private:
  static bool is_inited;                                                // = false
  static LARGE_INTEGER frequency;
  static void init()
  {
    if(QueryPerformanceFrequency(&frequency) == 0)
      throw std::logic_error("QueryPerformanceCounter not supported: " + std::to_string(GetLastError()));
  }
};

For Linux it is even easier.对于 Linux,它甚至更容易。 Just read the man page of clock_gettime and modify the code above.只需阅读clock_gettime的手册页并修改上面的代码即可。

GCC 5.3.0 implementation GCC 5.3.0 实施

C++ stdlib is inside GCC source: C++ stdlib 位于 GCC 源代码中:

Then CLOCK_REALTIME vs CLOCK_MONOTONIC is explained at: Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?然后CLOCK_REALTIMECLOCK_MONOTONIC的解释如下: CLOCK_REALTIME 和 CLOCK_MONOTONIC 之间的区别?

Maybe, the most significant difference is the fact that the starting point of std::chrono:system_clock is the 1.1.1970, so-called UNIX-epoch.也许,最显着的区别是std::chrono:system_clock的起点是 1.1.1970,即所谓的 UNIX-epoch。 On the other side, for std::chrono::steady_clock typically the boot time of your PC and it's most suitable for measuring intervals.另一方面,对于std::chrono::steady_clock ,通常是 PC 的启动时间,它最适合测量间隔。

Relevant talk about chrono by Howard Hinnant , author of chrono : chrono 的作者 Howard Hinnant 对 chrono 的相关chrono

don't use high_resolution_clock , as it's an alias for one of these:不要使用high_resolution_clock ,因为它是其中之一的别名:

  • system_clock : it's like a regular clock, use it for time/date related stuff system_clock :它就像一个普通时钟,用于时间/日期相关的东西
  • steady_clock : it's like a stopwatch, use it for timing things. steady_clock :它就像一个秒表,用它来计时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 stable_clock 与 system_clock 之间的区别? - Difference between steady_clock vs system_clock? 在C ++实现中std :: chrono :: system_clock vs std :: chrono :: steady_clock的精度是多少? - Precision of std::chrono::system_clock vs std::chrono::steady_clock across C++ implementations? 不匹配的类型 'std::chrono::_V2::steady_clock' 和 'std::chrono::_V2::system_clock' - mismatched types 'std::chrono::_V2::steady_clock' and 'std::chrono::_V2::system_clock' 我怎么知道我的 `std::chrono::high_resolution_clock` 对应于 `steady_clock` 或 `system_clock` 的别名,或其他? - How can I know my `std::chrono::high_resolution_clock` correspond to the alias of `steady_clock` or `system_clock`, or other? 同时获取steady_clock和system_clock - Get steady_clock and system_clock at the same time 在整个系统中使用 std::chrono::steady_clock 时间是否正确? - Is it correct to use std::chrono::steady_clock time across the system? 使用std :: chrono :: steady_clock在线程/异步中对代码进行基准测试 - Using std::chrono::steady_clock to benchmark code in a thread/async std :: chrono :: steady_clock :: now如何报告错误? - How does std::chrono::steady_clock::now report errors? 持久性 std::chrono time_point<steady_clock></steady_clock> - Persistent std::chrono time_point<steady_clock> 是否确保 2 个连续的 std::chrono::steady_clock::now() 不相等? - Is it ensured that 2 sequential std::chrono::steady_clock::now() will not be equal?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM