C++:是否可以以纳秒精度获取实时(与当前 CPU 频率和负载无关)作为 unix 时间戳?

问题描述 投票:0回答:1

目前我使用当前 CPU 频率和 __rdtsc() 函数将其计算为 100 纳秒间隔(Windows FileTime):

typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> TimePoint;

void Services::GetRealTime(int64_t* RTime) // Time in 100-nanosecond intervals
{
    *RTime = RealTime + (INT64)((__rdtsc() - rdtscPrevVal) * (1.0 / CPUFrequency));
}

void    Services::GetRealTime(TimePoint& timePoint) 
{
    int64_t realTime;
    GetRealTime(&realTime);
    timePoint = TimePoint(std::chrono::duration_cast<TimePoint::duration>(std::chrono::nanoseconds(realTime * 100)));
}

但我确信 C++ 有更可靠、跨平台和精确的方法来做到这一点。我该怎么做?

std::chrono::steady_clock::now()
能完成这项工作吗?

我需要精确测量事件时间(以纳秒为单位),与当前 CPU 负载和限制无关。

c++ time c++-chrono
1个回答
0
投票

现在,这里有一些关于时钟和其他东西的想法。

首先,C++ 给你

std::chrono::high_resolution_clock
。但它并不为您提供有关实际分辨率的任何保证。如果您想要保证,您必须进入操作系统级别并仔细阅读他们有关实际分辨率与返回值的文档 - 仅仅因为某些内容返回“纳秒”并不意味着它正在测量纳秒。

现在,“unix 时间戳”实际上并不存在,所以我假设你正在谈论类似

time_t
的东西,除了放大到纳秒。从 C++ 的角度来看,这意味着将时间点转换为
std::chrono::system_clock
——不幸的是,这可能没有纳秒精度。另外,上次我尝试使用
std::chrono::clock_cast
时,我的编译器还没有。

假设您有一个可用的

std::chrono::clock_cast
,您仍然可以尝试执行以下操作:从
high_resolution_clock
时间点削减纳秒,转换为
system_clock
,获取
time_t
,乘以 1000000000,然后添加纳秒。不过,这就是“如果”你有
clock_cast
,以及“如果”你有纳秒开始......

归根结底,如果我确实想要纳秒,我可能会坚持使用操作系统调用。只要我们没有将

std::chrono::nano_clock
定义为“系统可以召集的尽可能接近纳秒时钟”,可用的时钟就无法满足要求。

如果您没有

clock_cast
,转换仍然是可能的,尽管有点黑客,并且它们可能会比
clock_cast
失去更多的准确性。那么,实际上,如果您想要“事件时间”,为什么它必须是“实时”呢?对于日志输出或类似的东西,准确性的损失不会是一个大问题,恕我直言。

但是,作为避免操作系统调用的简单解决方法,您可以键入定义您自己的“MyClock”,并检查您使用的系统实际提供的功能。例如,在 Windows 上,

std::chrono::file_clock
可能与您当前使用的 100ns 分辨率时钟相同,只不过包装在 C++ 时钟中。不同平台上的人可能会将
MyClock
输入到不同的时钟,因此一些
#ifdef
可以提供合理的可移植性。

另外,虽然我自己没有检查过这个选项,但也许可以在编译时检查各种时钟类型的分辨率,并且基本上让编译器通过查看诸如

MyClock
之类的内容来为您计算出
high_resolution_clock
file_clock
并选择最适合您的一个。

不过,这仍然会限制您使用 C++ 实现实际提供的时钟。操作系统可能有您可能喜欢的东西,但 C++ 实现可能不会包装那个...

© www.soinside.com 2019 - 2024. All rights reserved.