gpt4 book ai didi

c++ - C++ 实现中 std::chrono::system_clock 与 std::chrono::steady_clock 的精度?

转载 作者:行者123 更新时间:2023-11-30 02:16:32 30 4
gpt4 key购买 nike

以下程序:

#include <chrono>
#include <iostream>
#include <vector>

inline uint64_t now() {
return std::chrono::duration_cast
<std::chrono::nanoseconds>
(std::chrono::system_clock::now()
.time_since_epoch())
.count();
}

int main() {
std::vector<uint64_t> v;
for (int i = 0; i < 1000; i++)
v.push_back(now());

for (int i = 0; i < v.size()-1; i++)
std::cout << v[i+1] - v[i] << std::endl;
}

打印 250 到 300 范围内的数字:

g++ (Ubuntu 8.2.0-7ubuntu1) 8.2.0

与:

Linux 4.18.0-15-generic #16-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux

意思是 std::chrono::system_clock 在这个系统上是纳秒精度(很可能是 gettimeofday 对吗?)。我有几个问题:

  1. 在这个系统上 std::chrono::system_clockstd::chrono::steady_clock 有什么区别? (是的,我知道它们在标准中有不同的规定,我正在考虑这个实现。)

  2. 所有 libstdc++ 目标的答案是否相同?

  3. 所有 libc++ 目标的答案是否相同?

  4. Windows/MSVC 目标上的答案是否相同?

最佳答案

我不确定您是在问您想要得到回答的问题。我看到的一件事是您询问稳定时钟和系统时钟之间在精度方面的差异。第二个,仅从代码片段来看,是关于 system_clock::now、duration_cast、vector::push_back/vector::insert 和(隐式)vector::resize 的性能。

如果您不介意的话,我会尝试回答这两个问题中的第一个:

  • 这些时钟的关键是一个 (system_clock) 适合与任何物理日历互操作,因此有时可以返回(随着夏季/冬季时间转换当某人或某事更改系统时机器上的时间,请参阅 Difference between std::system_clock and std::steady_clock? ),而另一个(steady_clock)保证只前进并且适用于例如。测量 push_back 的长度。
  • 无法保证这些时钟的分辨率。这就是为什么你应该尽可能保持时钟的持续时间类型,并且只在打印之前使用 .count() 访问器;但是,由于无法保证所使用的期限,您可能应该
    1. 对稳定的东西进行 duration_cast,
    2. 或者执行一些奇特的后缀选择,使用句点作为一些元程序的参数。
  • 无法保证 time_since_epoch() 的含义,并且在 C++20 之前无法比较属于两个不同时钟的 time_points/durations
  • 并且,请记住,对于任何系统上任何时钟的周期分辨率,我们都无法保证;我发现很难(写一些花哨的模板),甚至不能保证周期可以被 1000 整除......对于其中一个时钟,其中一个库使用 1 over 10^8 作为周期.. .

因此,询问任何特定的实现并希望它们的常量也将在其他实现中使用——即使对于同一供应商——是不可取的。我总是尝试使用时钟的::time_point 或其::duration,或者,作为最后的手段,毫秒或纳秒,这取决于我测量的是什么以及测量的东西可以飞多快。

另请注意,有 system_clock::(to/from)_time_t() 函数,即使 system_clock::duration 具有更精细的周期,它肯定会产生 1 比 1 的值(秒)。

修改后的片段,使用 steady_clock,它的 time_point 和尽可能晚的调用 duration_cast 将是:

#include <chrono>
#include <iostream>
#include <vector>

int main() {
using namespace std::chrono;
using clock = steady_clock;

std::vector<clock::time_point> v;
for (int i = 0; i < 1000; i++)
v.push_back(clock::now());

for (size_t i = 0; i < v.size()-1; i++) {
std::cout
<< duration_cast<nanoseconds>(
v[i+1] - v[i]
).count()
<< "ns\n";
}
}

编辑:哦,还有一件事是原始代码中没有任何内容可以证明您的库使用 nano 作为 system_clock 中的句点。你正在做一个 duration_cast (如果必须的话使用整数除法)并从中获取周期,但是持续时间不同,比如 duration_cast >,你也可以在下面的某个地方得到非零最低的 1000。不太可能,但绝对有可能。

编辑 2: 谢天谢地,这很复杂。更改了第一个要点中 system_clock 不稳定的原因。

关于c++ - C++ 实现中 std::chrono::system_clock 与 std::chrono::steady_clock 的精度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54741852/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com