为什么 chrono::system_clock returns 微秒而 clock_gettime returns 纳秒
Why does chrono::system_clock returns microseconds whereas clock_gettime returns nanoseconds
std::chrono::system_clock::time_since_epoch().count() 以微秒为单位给出结果。
我想要以纳秒为单位的当前时间。但是我不能使用 high_resolution_clock 因为在我的系统上它是 steady_clock(单调时钟)的别名。
我知道我的系统支持纳秒,因为如果我使用 clock_gettime(CLOCK_REALTIME, &ts) 我会得到一个正确的纳秒分辨率纪元时间。
如何告诉 std::chrono 使用纳秒分辨率?我想避免使用 clock_gettime 并坚持使用 cpp 包装器。
I am getting a correct nanosecond-resolution epoch time.
你是吗? clock_gettime
需要 到 return 纳秒级的时间,无论您访问的是什么时钟。这并不意味着 CLOCK_REALTIME
实际上提供了这个分辨率。它可能内部只有微秒分辨率,并通过乘以 1000 来表示纳秒。
相比之下,计时时钟的实际分辨率由实现指定。它不是 UI 的强制性部分;它可能因系统而异 and 因时钟而异。因此,如果特定实现的 system_clock::period
以微秒为单位,那么这就是该实现愿意声称提供的所有分辨率。
也许实施可以提供更多分辨率,但如果可以的话,它可能会这么说。因此,如果没有,则意味着实现声称提供更高的分辨率会让人感到不舒服。
但是,如果您觉得 clock_gettime
确实提供了更好的分辨率(而不是简单地提供更多数字),您可以使用它。在 C++20 中,system_clock
是明确的 UNIX 时间。因此,如果您的时间以纳秒为单位,则可以将其转换为 time_point<system_clock, nanoseconds>
:
namespace chrono = std::chrono;
...
using nano_sys = chrono::time_point<chrono::system_clock, chrono::nanoseconds>;
auto sys_tp_ns = nano_sys(chrono::nanoseconds(time_in_nanoseconds));
How can I tell std::chrono to use the nanosecond resolution?
这听起来很适合编写您自己的自定义时钟。这比听起来容易得多:
#include <time.h>
#include <chrono>
struct my_clock
{
using duration = std::chrono::nanoseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<my_clock>;
static constexpr bool is_steady = false;
static time_point now()
{
timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts))
throw 1;
using sec = std::chrono::seconds;
return time_point{sec{ts.tv_sec}+duration{ts.tv_nsec}};
}
};
只需让您的 now()
与 CLOCK_REALTIME
通话 clock_gettime
。然后将 return 打包成 chrono::time_point
分辨率 nanoseconds
。
警告,我刚刚在 macOS 上试过这个并连续调用了 now()
两次。它每次都打印出相同的纳秒数。而且调用不可能在纳秒内执行。所以我得到的是纳秒精度,但不是纳秒精度。
如果您希望 my_clock
参与 C++20 std::chrono::clock_cast
设施(如 Nicol Bolas 所建议
在下面的评论中),将这两个静态成员函数添加到 my_clock
:
template<typename Duration>
static
std::chrono::time_point<std::chrono::system_clock, Duration>
to_sys(const std::chrono::time_point<my_clock, Duration>& tp)
{
return std::chrono::time_point<std::chrono::system_clock, Duration>
{tp.time_since_epoch()};
}
template<typename Duration>
static
std::chrono::time_point<my_clock, Duration>
from_sys(const std::chrono::time_point<std::chrono::system_clock, Duration>& tp)
{
return std::chrono::time_point<my_clock, Duration>{tp.time_since_epoch()};
}
现在你可以这样说:
cout << clock_cast<system_clock>(my_clock::now()) << '\n';
您还可以 clock_cast
往返于 所有 参与 clock_cast
设施的其他 C++20 和自定义时钟。
首先,请注意,在 GCC+libstc++ 上,std::chrono 只是围绕 clock_gettime() 的语法糖的薄包装。你在这里谈论同样的事情。 std::chrono 使用 clock_gettime()。
system_clock::time_point
system_clock::now() noexcept
{
timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return time_point(duration(chrono::seconds(tp.tv_sec)
+ chrono::nanoseconds(tp.tv_nsec)));
}
来源:https://code.woboq.org/gcc/libstdc++-v3/src/c++11/chrono.cc.html
(以上代码已清理)
所以精度就在那里,你只需要用
在纳秒内检索它
uint64_t utc_now_nanos() {
std::chrono::steady_clock::time_point tp = std::chrono::steady_clock::now();
return std::chrono::time_point_cast<std::chrono::nanoseconds>(tp).time_since_epoch().count();
}
std::chrono::system_clock::time_since_epoch().count() 以微秒为单位给出结果。
我想要以纳秒为单位的当前时间。但是我不能使用 high_resolution_clock 因为在我的系统上它是 steady_clock(单调时钟)的别名。
我知道我的系统支持纳秒,因为如果我使用 clock_gettime(CLOCK_REALTIME, &ts) 我会得到一个正确的纳秒分辨率纪元时间。
如何告诉 std::chrono 使用纳秒分辨率?我想避免使用 clock_gettime 并坚持使用 cpp 包装器。
I am getting a correct nanosecond-resolution epoch time.
你是吗? clock_gettime
需要 到 return 纳秒级的时间,无论您访问的是什么时钟。这并不意味着 CLOCK_REALTIME
实际上提供了这个分辨率。它可能内部只有微秒分辨率,并通过乘以 1000 来表示纳秒。
相比之下,计时时钟的实际分辨率由实现指定。它不是 UI 的强制性部分;它可能因系统而异 and 因时钟而异。因此,如果特定实现的 system_clock::period
以微秒为单位,那么这就是该实现愿意声称提供的所有分辨率。
也许实施可以提供更多分辨率,但如果可以的话,它可能会这么说。因此,如果没有,则意味着实现声称提供更高的分辨率会让人感到不舒服。
但是,如果您觉得 clock_gettime
确实提供了更好的分辨率(而不是简单地提供更多数字),您可以使用它。在 C++20 中,system_clock
是明确的 UNIX 时间。因此,如果您的时间以纳秒为单位,则可以将其转换为 time_point<system_clock, nanoseconds>
:
namespace chrono = std::chrono;
...
using nano_sys = chrono::time_point<chrono::system_clock, chrono::nanoseconds>;
auto sys_tp_ns = nano_sys(chrono::nanoseconds(time_in_nanoseconds));
How can I tell std::chrono to use the nanosecond resolution?
这听起来很适合编写您自己的自定义时钟。这比听起来容易得多:
#include <time.h>
#include <chrono>
struct my_clock
{
using duration = std::chrono::nanoseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<my_clock>;
static constexpr bool is_steady = false;
static time_point now()
{
timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts))
throw 1;
using sec = std::chrono::seconds;
return time_point{sec{ts.tv_sec}+duration{ts.tv_nsec}};
}
};
只需让您的 now()
与 CLOCK_REALTIME
通话 clock_gettime
。然后将 return 打包成 chrono::time_point
分辨率 nanoseconds
。
警告,我刚刚在 macOS 上试过这个并连续调用了 now()
两次。它每次都打印出相同的纳秒数。而且调用不可能在纳秒内执行。所以我得到的是纳秒精度,但不是纳秒精度。
如果您希望 my_clock
参与 C++20 std::chrono::clock_cast
设施(如 Nicol Bolas 所建议
在下面的评论中),将这两个静态成员函数添加到 my_clock
:
template<typename Duration>
static
std::chrono::time_point<std::chrono::system_clock, Duration>
to_sys(const std::chrono::time_point<my_clock, Duration>& tp)
{
return std::chrono::time_point<std::chrono::system_clock, Duration>
{tp.time_since_epoch()};
}
template<typename Duration>
static
std::chrono::time_point<my_clock, Duration>
from_sys(const std::chrono::time_point<std::chrono::system_clock, Duration>& tp)
{
return std::chrono::time_point<my_clock, Duration>{tp.time_since_epoch()};
}
现在你可以这样说:
cout << clock_cast<system_clock>(my_clock::now()) << '\n';
您还可以 clock_cast
往返于 所有 参与 clock_cast
设施的其他 C++20 和自定义时钟。
首先,请注意,在 GCC+libstc++ 上,std::chrono 只是围绕 clock_gettime() 的语法糖的薄包装。你在这里谈论同样的事情。 std::chrono 使用 clock_gettime()。
system_clock::time_point
system_clock::now() noexcept
{
timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return time_point(duration(chrono::seconds(tp.tv_sec)
+ chrono::nanoseconds(tp.tv_nsec)));
}
来源:https://code.woboq.org/gcc/libstdc++-v3/src/c++11/chrono.cc.html
(以上代码已清理)
所以精度就在那里,你只需要用
在纳秒内检索它uint64_t utc_now_nanos() {
std::chrono::steady_clock::time_point tp = std::chrono::steady_clock::now();
return std::chrono::time_point_cast<std::chrono::nanoseconds>(tp).time_since_epoch().count();
}