【问题标题】:chrono give different measures at same functionchrono 在同一功能上给出不同的度量
【发布时间】:2021-05-19 16:55:45
【问题描述】:

我正在尝试测量执行时间。 我在 Windows 10 上并使用 gcc 编译器。

start_t = chrono::system_clock::now();
tree->insert();
end_t = chrono::system_clock::now();
rslt_period = chrono::duration_cast<chrono::nanoseconds>(end_t - start_t);

这是我测量时间的代码 bp_w-&gt;insert() 函数 insert 在内部像 follow 一样工作(只是伪代码)

insert(){
    _load_node(node);
    // do something //
    _save_node(node, addr);
}

_save_node(n){
    ofstream file(name);
    file.write(n);
    file.close();
}

_load_node(n, addr){
    ifstream file(name);
    file.read_from(n, addr);
    file.close();
}

实际结果是, read 是_load_node 执行次数。 write 是_save_node 执行次数。 时间是纳秒。

read  write time
1     1     1000000
1     1     0
2     1     0
1     1     0
1     1     0
1     1     0
2     1     0
1     1     1004000
1     1     1005000
1     1     0
1     1     0
1     1     15621000

我不知道为什么会出现这个结果并想知道。

【问题讨论】:

  • 在进行这样的测量时使用steady_clock
  • 感谢您提供的好信息。我会尝试的,但对结果感到好奇。你能给个主意吗?我想知道为什么会这样。
  • 时间可能不确定。在 Windows 上,您可以获得的最小滴答声可能是 1/64 秒,这会导致垃圾结果,例如数百个 0,然后是一个 15 毫秒的跳跃。 chrono 有能力提供纳秒,但通常它下面的系统无法为您提供接近此的分辨率。
  • 我只能猜测。时钟似乎不支持比微秒更高的分辨率。一些插入需要很短的时间。这取决于您的代码中发生了什么。您上面的伪代码很可能无法编译。如果您将minimal reproducible example 放在一起,可能会更容易说出来。
  • 如果你在 Windows 上,你可以使用GetSystemTimePreciseAsFileTimeQueryPerformanceCounter

标签: c++ chrono time-measurement


【解决方案1】:

您要测量的内容不明确。

“这段代码运行了多长时间”看起来很简单。但是,实际上,您的意思是“我的代码占用了多少 CPU 周期”?或者我的程序和其他正在运行的程序之间有多少个周期?您是否考虑了在 CPU 上加载/卸载它的时间?您是否考虑到使用电池时 CPU 会被节流?您是否要考虑访问位于主板上的主时钟的时间(就计算而言非常远)。

因此,在实践中,时间会受到很多因素的影响,而测量它的简单事实会减慢一切。不要指望纳秒精度。微博,也许吧。米利斯,当然。

因此,这会使您处于任何测量值都会波动很大的位置。明智的方法是在多次测量中对其进行平均。或者,更好的是,(对不同的数据)执行相同的操作一千(百万?)次,然后将结果除以一千。

然后,您将在准确性上获得显着提高。

在代码中:

start_t = chrono::system_clock::now();
for(int i = 0; i < 1000000; i++)
tree->insert();
end_t = chrono::system_clock::now();

【讨论】:

    【解决方案2】:

    您使用了错误的时钟。 system_clock 由于分辨率低且不单调,因此不适用于时间间隔。

    请改用steady_clock。它保证是单调的,并且具有足够低的分辨率以供使用。

    【讨论】:

    • 必须是单调的,并且具有足够低的分辨率才能使用。 是,单调,否足够低的分辨率有用。它在底层系统可以提供的支持下尽其所能。
    • 这是真的,但还不够。您不能为单个insert 计时并期待有意义的阅读。如果这个得到(或没有得到)一次性上下文切换或页面错误怎么办?如果操作系统决定现在是执行某些重要任务的时候了怎么办。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 2019-01-12
    相关资源
    最近更新 更多