使用 std::chrono 的时间戳 - 如何根据相对时间 'filter' 数据?
Time-stamping using std::chrono - How to 'filter' data based on relative time?
我想对我生成的数据流进行时间标记,为此我想使用 std::chrono::steady_clock.
这些时间戳与数据一起存储(作为 uint64 值的数组?),我稍后需要再次处理这些时间戳。
现在,到目前为止我还没有使用过 std::chrono 库,所以我确实需要一些关于这个库的语法和最佳实践的帮助。
我可以使用以下方法获取和存储值:
uint64_t timestamp = std::chrono::steady_clock::now().time_since_epoch().count();
但我怎样才能做到最好:
读取数据时从 uint64 创建一个时间点?
获取 steady_clock?
的每秒滴答数 (uint64) 值
找到一个位于给定时间点之前特定时间(以秒为单位)的“截止”时间点(如 uint64)?
以上代码片段将不胜感激。
我想结合以上三者来执行以下操作:有一个(增加的)时间戳值数组(如 uint64),我想截断它,以便所有数据 'older' 比最后一个-时间戳减去 X 秒被丢弃。
像往常一样看起来不错的地方是参考手册:
https://en.cppreference.com/w/cpp/chrono
在这种情况下,您正在寻找:
https://en.cppreference.com/w/cpp/chrono/clock_time_conversion
因为您确实使用了以“纪元”1/1/70 为原点、以毫秒为单位的时钟。
然后只需对持续时间使用算术来完成你想要的截止操作:
https://en.cppreference.com/w/cpp/chrono/duration
每个链接页面的底部都有代码示例。
让我们看看您可能会在 chrono 的 cppreference 文档中使用的功能。
首先,您需要决定要使用哪个时钟。有您建议的 steady_clock
、high_resolution_clock
和 system_clock
。
high_resolution_clock
依赖于实现,所以除非我们真的需要它,否则让我们把它收起来。 steady_clock
保证是单调的,但不能保证您获得的值的含义。它非常适合对事件进行排序或测量它们的间隔,但您无法从中获取时间点。
另一方面,system_clock
有一个含义,它是UNIX纪元,所以你可以从中得到一个时间值,但不保证是单调的。
要获得 steady_clock
的周期(一个报价的持续时间),您有 period
成员:
auto period = std::chrono::steady_clock::period();
std::cout << "Clock period " << period.num << " / " << period.den << " seconds" << std::endl;
std::cout << "Clock period " << static_cast<double>(period.num) / period.den << " seconds" << std::endl;
假设您想使用 steady_clock
值过滤最近几秒内发生的事件,您首先需要计算所需时间段内的滴答数,然后从 now
中减去它.大致如下:
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t t_c = std::chrono::system_clock::to_time_t(now - std::chrono::seconds(10));
并使用t_c
作为分界点。
但是,不要依赖 std::chrono::steady_clock::now().time_since_epoch().count();
来获得有意义的东西 - 只是一个数字。 steady_clock
的纪元通常是引导时间。如果你需要一个时间,你应该使用system_clock
(记住这不是单调的)。
C++20a 引入了更多时钟,可转换为时间。
由于今天我花了太长时间才从各种来源弄清楚,所以我将post 此处作为我的解决方案self-answer。 (如果有不正确的地方或可以做得更好,我将不胜感激。)
获取时钟的周期(以秒为单位)和 ticks-per-second 值
using namespace std::chrono;
auto period = system_clock::period();
double period_s = (double) period.num / period.den;
uint64 tps = period.den / period.num;
获取时钟的时间点(现在)作为 time-stamping 数据流的 uint64 值
using namespace std::chrono;
system_clock::time_point tp_now = system_clock::now();
uint64 nowAsTicks = tp_now.time_since_epoch().count();
根据存储的 uint64 值获取时钟的时间点
using namespace std::chrono;
uint64 givenTicks = 12345; // Whatever the value was
system_clock::time_point tp_recreated = system_clock::time_point{} + system_clock::duration(givenTicks);
uint64 recreatedTicks = tp_now.time_since_epoch().count();
Assert( givenTicks == recreatedTicks ); // has to be true now
最后一个(uint64 到时间点)最让我困扰。需要的 key-insights 是:
(在 Win10 上)system_clock 使用 100 纳秒的 time-resolution。因此不能直接将 std::chrono::nanoseconds
添加到其本机时间点。 (std::chrono:system_clock_time_point
)
但是,由于滴答是 100 纳秒,因此也不能使用下一个更高的持续时间单位(微秒),因为它不能表示为整数值。
可以使用 显式 转换为微秒,但这会失去滴答声的 0.1us 分辨率。
正确的做法是使用system_clock自身的duration,直接用存储的tick值初始化
在我的搜索中,我发现以下资源最有帮助:
Lecture of Howard Hinnant on YouTube - 非常有帮助。我希望我能从这里开始。
cppreference.com 在 time_point and duration and time_since_epoch
cplusplus.com 在 steady clock and time_point
我想对我生成的数据流进行时间标记,为此我想使用 std::chrono::steady_clock.
这些时间戳与数据一起存储(作为 uint64 值的数组?),我稍后需要再次处理这些时间戳。
现在,到目前为止我还没有使用过 std::chrono 库,所以我确实需要一些关于这个库的语法和最佳实践的帮助。
我可以使用以下方法获取和存储值:
uint64_t timestamp = std::chrono::steady_clock::now().time_since_epoch().count();
但我怎样才能做到最好:
读取数据时从 uint64 创建一个时间点?
获取 steady_clock?
的每秒滴答数 (uint64) 值找到一个位于给定时间点之前特定时间(以秒为单位)的“截止”时间点(如 uint64)?
以上代码片段将不胜感激。
我想结合以上三者来执行以下操作:有一个(增加的)时间戳值数组(如 uint64),我想截断它,以便所有数据 'older' 比最后一个-时间戳减去 X 秒被丢弃。
像往常一样看起来不错的地方是参考手册:
https://en.cppreference.com/w/cpp/chrono
在这种情况下,您正在寻找:
https://en.cppreference.com/w/cpp/chrono/clock_time_conversion
因为您确实使用了以“纪元”1/1/70 为原点、以毫秒为单位的时钟。 然后只需对持续时间使用算术来完成你想要的截止操作:
https://en.cppreference.com/w/cpp/chrono/duration
每个链接页面的底部都有代码示例。
让我们看看您可能会在 chrono 的 cppreference 文档中使用的功能。
首先,您需要决定要使用哪个时钟。有您建议的 steady_clock
、high_resolution_clock
和 system_clock
。
high_resolution_clock
依赖于实现,所以除非我们真的需要它,否则让我们把它收起来。 steady_clock
保证是单调的,但不能保证您获得的值的含义。它非常适合对事件进行排序或测量它们的间隔,但您无法从中获取时间点。
另一方面,system_clock
有一个含义,它是UNIX纪元,所以你可以从中得到一个时间值,但不保证是单调的。
要获得 steady_clock
的周期(一个报价的持续时间),您有 period
成员:
auto period = std::chrono::steady_clock::period();
std::cout << "Clock period " << period.num << " / " << period.den << " seconds" << std::endl;
std::cout << "Clock period " << static_cast<double>(period.num) / period.den << " seconds" << std::endl;
假设您想使用 steady_clock
值过滤最近几秒内发生的事件,您首先需要计算所需时间段内的滴答数,然后从 now
中减去它.大致如下:
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t t_c = std::chrono::system_clock::to_time_t(now - std::chrono::seconds(10));
并使用t_c
作为分界点。
但是,不要依赖 std::chrono::steady_clock::now().time_since_epoch().count();
来获得有意义的东西 - 只是一个数字。 steady_clock
的纪元通常是引导时间。如果你需要一个时间,你应该使用system_clock
(记住这不是单调的)。
C++20a 引入了更多时钟,可转换为时间。
由于今天我花了太长时间才从各种来源弄清楚,所以我将post 此处作为我的解决方案self-answer。 (如果有不正确的地方或可以做得更好,我将不胜感激。)
获取时钟的周期(以秒为单位)和 ticks-per-second 值
using namespace std::chrono;
auto period = system_clock::period();
double period_s = (double) period.num / period.den;
uint64 tps = period.den / period.num;
获取时钟的时间点(现在)作为 time-stamping 数据流的 uint64 值
using namespace std::chrono;
system_clock::time_point tp_now = system_clock::now();
uint64 nowAsTicks = tp_now.time_since_epoch().count();
根据存储的 uint64 值获取时钟的时间点
using namespace std::chrono;
uint64 givenTicks = 12345; // Whatever the value was
system_clock::time_point tp_recreated = system_clock::time_point{} + system_clock::duration(givenTicks);
uint64 recreatedTicks = tp_now.time_since_epoch().count();
Assert( givenTicks == recreatedTicks ); // has to be true now
最后一个(uint64 到时间点)最让我困扰。需要的 key-insights 是:
(在 Win10 上)system_clock 使用 100 纳秒的 time-resolution。因此不能直接将
std::chrono::nanoseconds
添加到其本机时间点。 (std::chrono:system_clock_time_point
)但是,由于滴答是 100 纳秒,因此也不能使用下一个更高的持续时间单位(微秒),因为它不能表示为整数值。
可以使用 显式 转换为微秒,但这会失去滴答声的 0.1us 分辨率。
正确的做法是使用system_clock自身的duration,直接用存储的tick值初始化
在我的搜索中,我发现以下资源最有帮助:
Lecture of Howard Hinnant on YouTube - 非常有帮助。我希望我能从这里开始。
cppreference.com 在 time_point and duration and time_since_epoch
cplusplus.com 在 steady clock and time_point