【问题标题】:Get nanoseconds since midnight with the lowest latency以最低延迟获得自午夜以来的纳秒
【发布时间】:2019-11-17 21:58:02
【问题描述】:

我想获取自午夜以来的当前纳秒数,延迟最低。

我的平台是带有 Clang 的 Linux/Centos 7。我关心可移植性。

我找到了这个<chrono> struct, 但它们除以秒/毫秒等以获得结果。

我还发现这个可以修改为纳秒:

struct timeval tv;
int msec = -1;
if (gettimeofday(&tv, NULL) == 0)
{
    msec = ((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
}

https://stackoverflow.com/a/10499119/997112

但他们再次使用除法。 有什么更快的方法,避免模数和除法?

我认为最快的方法是:

  • 抓紧时间
  • 多个小时、分钟、秒乘以必要的纳秒,然后将当前的纳秒数加到总数中

?

【问题讨论】:

  • 我记得上次我这样做的时候,有一个内核配置选项可以从 CPU 的时基寄存器完全在用户空间中为gettimeofday() 提供服务。如果您担心分割,也许您可​​以存储原始值并稍后处理?
  • 现在整数除法不是很快吗?你为什么这么担心?
  • @marko 我会使用 rdtsc() 但我将 now() 与自午夜以来为纳秒的数据包时间戳进行比较。
  • @user997112:处理这些消息所花费的时间可能会使整数除法相形见绌。为什么你特别需要纳秒?
  • @user997112:另外,从午夜开始的时间很重要吗?因为只要用户重置系统时钟,“午夜”就会发生变化。或更改时区。仅供参考:gettimeofday肯定需要超过 60 个周期。

标签: c++ linux performance time


【解决方案1】:

没有任何硬件可以提供纳秒计数器;因此,提供其他东西(例如“CPU 周期”)的硬件必须在某处由软件使用和扩展。

Linux 上的clock_gettime() 函数将为您扩展到纳秒级。更重要的是(取决于安全性与性能的妥协),这可以纯粹在用户空间中完成,避免调用内核 API 的开销(这可能比微不足道的划分至少贵 10 倍)。

但是;在这些规模上,您需要非常具体地了解您真正想要的东西。例如;闰秒期间会发生什么? 2 台计算机可能不同意,因为一台配置为涂抹闰秒,而另一台未配置。

再举一个例子;如果您想计算延迟(例如“latency = current_time_at_receiver - time_packet_says_it_was_sent”),那么 2 台计算机可能不同步(例如,发送者的时钟比接收者的时钟晚几秒钟,因此延迟最终为负数);为了解决这个问题,您可能需要一个训练阶段(有点像 NTP 协议),在该阶段您尝试估计两台计算机时间源之间的初始差异,然后进行监控/跟踪(尝试补偿任何长时间术语漂移)。

【讨论】:

  • 两台机器都是 NTP 或 PTP 同步的。我有数据包中自午夜以来的纳秒数,我需要接收器上的纳秒数。
  • "latency = current_time_at_receiver - time_packet_says_it_was_sent" 这正是我想要的
  • @user997112:在这种情况下,存在一个不可避免的困境——任何类型的同步(例如 PTP)的准确性取决于网络延迟;并且您无法以超过网络延迟所允许的精度来衡量网络延迟。
  • @user997112:根据您的目标(例如,用于基准测试,尤其是“请求和响应”协议)“往返时间/2”(仅涉及一台计算机的时间源)可能是一个不错的选择(可能包括服务器在接收请求和发送回复之间通知客户端“处理时间”,以便客户端可以计算“networking_latency_alone = (round_trip_time - processing_time) / 2”,并且仅使用服务器的时间源来计算处理时间) .
  • 您假设数据包输入 -> 数据包输出,但事实并非如此。我实际上只是在问我如何在接收器上获得自午夜以来的纳秒数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
  • 2010-11-07
  • 2018-03-11
  • 1970-01-01
  • 1970-01-01
  • 2013-09-29
相关资源
最近更新 更多