【问题标题】:Where does the time from `std::chrono::system_clock::now().time_since_epoch()` come from and can it block if accessed from multiple threads?`std::chrono::system_clock::now().time_since_epoch()` 的时间来自哪里,如果从多个线程访问它会阻塞吗?
【发布时间】:2017-10-14 02:38:35
【问题描述】:

std::chrono::system_clock::now().time_since_epoch() 来自哪里? 也就是说,它是与晶体振荡器(物理组件)的直接接口吗?

如果是晶振,是每个核心一个还是所有核心一个?

如果所有内核都有一个振荡器,如果多个线程同时访问它,它是否可以阻塞线程(低延迟环境)?

如果每个内核都有一个晶体振荡器,它们是如何同步的?

【问题讨论】:

  • 你有什么特别的实现吗?
  • @chris 你能详细说明你的意思吗?您是指 x86 vs arm 中的实现还是代码实现?
  • 最值得注意的是操作系统,因为 chrono 库很可能只是委托给操作系统调用以获取自纪元以来的系统时间。例如,Windows 有GetSystemTime。该标准很少会如此直接地提供细节,因为它限制了可以实施它的系统类型。
  • @chris 这将是在 Linux 的上下文中
  • SMP 系统的一个显着问题是内核必须为每个内核调整时期。所以有可能在一个线程中获取时间,同步,在另一个线程中获取它,并以稍早的时间结束。

标签: c++ time hardware chrono


【解决方案1】:

C++ 标准不关心system_clock::now() 是如何实现的。它只是指定

返回代表当前时间点的time_point 对象。

典型的 C++ 标准库实现将依赖底层 OS 系统调用来获取实际的系统时钟值来构造 time_point 对象。

在硬件实现方面,您需要考虑硬件架构。但通常系统时钟的维护成本始终存在,无论有多少进程/线程正在读取它。并且系统时钟获取被实现为一个轻量级的例程,不会导致线程阻塞,也不会成为多线程程序的性能瓶颈。

另外,std::chrono::system_clock::now().time_since_epoch() 是一个简单的观察者方法,它只返回 std::chrono::system_clock::now() 返回的 time_point 对象中嵌入的 duration 对象,它只涉及 C++ 结构复制。

【讨论】:

    【解决方案2】:

    标准规定std::chrono::system_clock如下:

    23.17.7.1 类 system_clock [time.clock.system]

    system_clock 类的对象表示系统范围实时时钟的挂钟时间。

    这有多重含义。首先,这个时钟的时间点可以通过std::chrono::system_clock::to_time_tstd::chrono::system_clock::from_time_ttime_t 时间相互转换,暗示时钟代表某种物理时间。其次,时钟被指定为“系统范围”,这意味着所有进程都应该从这个时钟中检索相同的time_point 值。

    实际上,这意味着此时钟通常是通过调用操作系统特定函数来检索某种时间来实现的,例如,您会在任务栏中看到。

    请注意,如果此时钟is_steady,则未指定。这意味着来自这个时钟的timepoints 不必总是前进。即使呼叫发生在物理时间的后期,您也可以获得更早的时间点。例如,如果用户通过某些操作系统设置调整时钟,就会发生这种情况。

    更接近你描述的是std::chrono::steady_clock

    23.17.7.2 类 stable_clock [time.clock.steady]

    steady_clock 类的对象表示时钟,其 time_point 的值不会随着物理时间的增加而减少,并且 time_point 的值以相对于实时的稳定速率提前。

    我们提到了两个要求。首先,时钟必须是单调的,所以时间永远不能“倒流”。其次,时钟是稳定的,所以这个时钟的每一刻都应该花费相同的物理时间。

    用某种硬件计数器(如循环计数器)来实现这个时钟感觉很自然。但要小心:这个时钟不必是系统范围的。这是,因此一个值可以例如从当前正在执行的 CPU 中获取,即使可能存在具有不同计数器的其他 CPU。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      相关资源
      最近更新 更多