不同时间段的时间



当前我正在使用boost::rational<std::uint64>来跟踪我的应用程序。

基本上,我有一个运行时间很长的时钟,它会被不同时间分辨率的不同组件滴答作响,例如1/50、1/30、1001/30000等。我想保持完美的精度,即没有浮点。boost::rational可以很好地用于此目的,但我认为使用std::chrono::duration进行此设计会更好。

但我的问题是,我如何在这里使用std::chrono::duration?由于它使用了一个编译时间段,我不太明白如何在需要保持精度的场景中使用它?

如果我理解您的问题,并且如果您在编译时知道所有不同的时间分辨率,那么以下内容将满足您的要求。您可以在所有不同的时间分辨率上使用common_type来计算正确的刻度周期,如下所示:

#include <cstdint>
#include <chrono>
struct clock
{
typedef std::uint64_t                      rep;
typedef std::common_type
<
std::chrono::duration<rep, std::ratio<1, 50>>,
std::chrono::duration<rep, std::ratio<1, 30>>,
std::chrono::duration<rep, std::ratio<1001, 30000>>
>::type                                    duration;
typedef duration::period                   period;
typedef std::chrono::time_point<clock>     time_point;
static const bool is_steady =              true;
static time_point now()
{
// just as an example
using namespace std::chrono;
return time_point(duration_cast<duration>(steady_clock::now().time_since_epoch()));
}
};

这将在编译时计算出最大的刻度周期,它将准确地代表您指定的每个分辨率。例如,用这个时钟可以准确地表示:

  • 1/50,有600个刻度
  • 1/30,有1000个刻度
  • 1001/30000,有1001个刻度

下面的代码练习这个clock,并使用此处描述的"chrono_io"功能不仅打印出时钟的运行时刻度数,还打印出时钟刻度的编译时间单位:

#include <iostream>
#include <thread>
#include "chrono_io"
int main()
{
auto t0 = clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(20));
auto t1 = clock::now();
std::cout << (t1-t0) << 'n';
}

对我来说,这个打印出来:

633 [1/30000]seconds

意思是:对now()的调用之间有633个时钟刻度,每个刻度的单位是1/30000秒。如果你不想受制于"chrono_io",你可以用clock::period::numclock::period::den检查你的时钟单位。

如果您的不同时间分辨率不是编译时间信息,那么您当前使用boost::rational的解决方案可能是最好的。

您可以将周期设置为1,并为Rep使用浮点类型。

我怀疑你可以对boost::rational做同样的事情,但你必须仔细观察std::chrono,我还没有做过。查看treat_as_floating_pointduration_values。还要试着弄清楚标准中"算术类型或模拟算术类型的类"的含义。

有人可能会合理地争辩说,如果boost::rational没有模拟算术类型,那么它就没有完成它的工作。但这并不一定意味着它真的做到了std::chrono::duration所期望的一切。

最新更新