首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >std::system_clock与std::steady_clock的差异?

std::system_clock与std::steady_clock的差异?
EN

Stack Overflow用户
提问于 2012-11-07 04:48:41
回答 5查看 58.5K关注 0票数 110

std::system_clockstd::steady_clock有什么区别?(举例说明不同的结果/行为将是很好的)。

如果我的目标是精确地测量函数的执行时间(就像基准),那么在std::system_clockstd::steady_clockstd::high_resolution_clock之间最好的选择是什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-11-07 04:54:57

来自N3376:

20.11.7.1时钟系统/1:

system_clock对象表示来自系统范围的实时时钟的挂钟时间.

20.11.7.2时钟稳定/1:

steady_clock类的对象表示时钟,其中time_point的值不会随着物理时间的推移而减少,而time_point的值相对于实时以稳定的速度前进。也就是说,钟是不可以调整的。

20.11.7.3时钟时间/1:

high_resolution_clock类的对象表示具有最短滴答周期的时钟。high_resolution_clock可以是system_clocksteady_clock的同义词。

例如,系统宽时钟可能会受到夏时制之类的影响,在这种情况下,将来某一时刻列出的实际时间实际上可能是过去的一个时间。(例如,在美国,秋天的时间向后移动一个小时,因此同一时间经历了“两次”)然而,steady_clock不允许受这些事情的影响。

在这种情况下,另一种思考“稳定”的方法是在20.11.3 time.clock.req/2表中定义的需求:

在表59中,C1C2表示时钟类型。t1t2是由C1::now()返回的值,其中调用返回t1发生在调用返回t2之前,而这两个调用都发生在C1::time_point::max()之前。注意:这意味着C1没有在t1t2之间转圈。-end注释表达式:C1::is_steady 返回:const bool 操作语义:如果true t1 <= t2总是真的,并且时钟滴答之间的时间是恒定的,则为false

这就是他们之间的不同之处。

如果您想做基准测试,您最好的选择可能是std::high_resolution_clock,因为您的平台很可能对此时钟使用高分辨率计时器(例如QueryPerformanceCounter )。但是,如果您正在进行基准测试,那么您应该考虑在基准测试中使用特定于平台的定时器,因为不同的平台处理这个问题的方式不同。例如,一些平台可能提供一些方法来确定程序所需时钟的实际数量(独立于运行在同一CPU上的其他进程)。更好的是,把你的手放在一个真正的剖析器上,然后使用它。

票数 78
EN

Stack Overflow用户

发布于 2012-11-07 09:13:17

比利提供了一个很好的答案,基于国际标准化组织C++标准,我完全同意。然而,故事的另一面是真实的生活。现在看来,在流行编译器的实现中,这些时钟实际上并没有什么区别:

gcc 4.8:

代码语言:javascript
运行
复制
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
   ...
#else
  typedef system_clock steady_clock;
#endif
  typedef system_clock high_resolution_clock;

Visual Studio 2012:

代码语言:javascript
运行
复制
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;

在gcc的情况下,您可以检查是否处理稳定的时钟,只需检查is_steady,并采取相应的行动。然而,VS2012似乎在这里欺骗了一点:-)

如果您需要高精度的时钟,我建议您现在编写符合C++11正式时钟接口的时钟,并等待实现赶上。这将比直接在代码中使用OS特定的API要好得多。对于Windows,您可以这样做:

代码语言:javascript
运行
复制
// 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()));
  }
};

对于Linux来说,这甚至更容易。只需阅读clock_gettime的手册页并修改上面的代码即可。

票数 49
EN

Stack Overflow用户

发布于 2016-12-17 21:56:49

GCC 5.3.0实现

C++ stdlib在GCC内部消息来源:

  • steady_clock转发给下列可用的第一个:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

然后,CLOCK_REALTIMECLOCK_MONOTONIC的解释是:单调?

票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13263277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档