扩展 std::chrono 功能以处理运行时(非编译时)恒定周期

fwy*_*ard 3 c++ time

我一直在 Linux 和 OSX 上尝试各种计时器,并想尝试使用 std::chrono 使用的相同接口来包装其中一些计时器。

对于在编译时具有明确定义的“周期”的定时器来说,这很容易做到,例如POSIX Clock_gettime() 系列、OSX 上的clock_get_time() 系列或gettimeofday()。

然而,有一些有用的计时器,其“周期”(虽然是常数)仅在运行时才知道。例如: - POSIX 规定时钟周期(CLOCKS_PER_SEC)在非 XSI 系统上可能是一个变量 - 在 Linux 上,times() 周期由 sysconf(_SC_CLK_TCK) 在运行时给出 - 在 OSX 上,周期mach_absolute_time() 在运行时由 mach_timebase_info() 给出 - 在最新的 Intel 处理器上,DST 寄存器以恒定速率滴答,但当然这只能在运行时确定

要将这些计时器包装在 std::chrono 接口中,一种可能是使用 std::chrono::nanosecond 周期,并将每个计时器的值转换为纳秒。另一种方法可能是使用浮点表示。然而,这两种方法都会给 now() 函数带来(非常小的)开销,以及(可能很小)的精度损失。

我试图追求的解决方案是定义一组类来表示此类“运行时常数”周期,其构建方式与 std::ratio 类相同。但是我预计这将需要重写所有相关的模板类和函数(因为它们假设 constexpr 值)。

如何将这些类型的计时器包装为 std:chrono ?

或者对时钟的时间周期使用非 constexpr 值?

How*_*ant 5

有谁有将此类计时器包装为 std:chrono 的经验吗?

事实上我确实如此。在 OSX 上,您感兴趣的平台之一。:-)

你提到:

在 OSX 上,mach_absolute_time() 的周期在运行时由 mach_timebase_info() 给出

完全正确。同样在 OSX 上,和的libc++实现实际上基于. 我是这段代码的作者,该代码是开源的,具有慷慨的许可(只要保留版权,就可以用它做任何你想做的事情)。high_resolution_clocksteady_clockmach_absolute_time

这是libc++steady_clock::now()的源代码。它的构建方式与您的猜测非常相似。返回之前,运行时间段将转换为纳秒。在 OS X 上,转换因子通常为 1,代码利用这一事实进行优化。然而,该代码足够通用,足以处理非 1 转换因子。

第一次调用时,now()查询运行时间转换因子到纳秒的成本很小。在一般情况下,计算浮点转换因子。在常见情况下(转换因子== 1),后续成本是通过函数指针调用的。我发现开销确实相当合理。

在 OS X 上,转换因子虽然要到运行时才确定,但仍然是一个常量(即不随程序执行而变化),因此只需要计算一次。

如果您的经期实际上是动态变化的,您将需要更多的基础设施来处理这个问题。本质上,您需要对周期与时间曲线进行积分(微积分),然后计算两个时间点之间的平均周期。这需要持续监控该周期随时间的变化,但这<chrono>并不是合适的工具。此类工具通常在操作系统级别处理。