std :: chrono有多准确?

Car*_*bon 7 c++ precision time c++-chrono

std::chrono宣称它可以将结果报告到纳秒级别.在典型的x86_64 Linux或Windows机器上,人们期望它的准确度如何?例如,对于10 ns,10μs,10 ms和10 s的测量,误差条是多少?

Zeb*_*ish 6

这很可能取决于硬件和操作系统。例如,当我问 Windows 使用 QueryPerformanceFrequency() 的时钟频率是多少时,我得到 3903987,如果你取倒数,你会得到大约 256 纳秒的时钟周期或分辨率。这是我的操作系统报告的值。

使用 std::chrono 根据文档,最小可表示持续时间为 high_resolution_clock::period::num / high_resolution_clock::period::den。

num 和 den 是分子和分母。std::chrono::high_resolution_clock 告诉我分子是 1,分母是 10 亿,据说对应于 1 纳秒:

std::cout << (double)std::chrono::high_resolution_clock::period::num /   
std::chrono::high_resolution_clock::period::den; // Results in a nanosecond.
Run Code Online (Sandbox Code Playgroud)

所以根据 std::chrono 我有一个纳秒分辨率,但我不相信它,因为本机操作系统系统调用更有可能报告更准确的频率/周期。

  • @Carbon 由于 `clock::now` 有其自身的开销,*并且*因为您的系统不是*实时*系统,因此总是会导致额外的不准确,因此对运行速度的保证较少CPU 将解决您的查询。示例:在调用 `clock::now()` 之间,您当前的进程可能会被另一个进程抢占几微秒。 (3认同)

vit*_*aut 5

计时时钟的准确性取决于实现,据我所知,没有标准 API 来查询它。在 POSIX 上,时钟通常使用 来实现clock_gettime,并且分辨率可以高达 1ns,如 所报告的那样clock_getres

但是,您可能需要考虑调用函数的开销now()(包括底层 API 的开销),该开销可能远高于报告的分辨率。它可以如下测量(godbolt):

#include <chrono>
#include <iostream>

int main() {
  const int num_measurements = 100;
  using clock = std::chrono::steady_clock;
  clock::time_point measurements[num_measurements];
  for (int i = 0; i < num_measurements; ++i) {
    measurements[i] = clock::now();
  }
  auto min_duration = clock::duration::max();
  for (int i = 1; i < num_measurements; ++i) {
    auto duration = measurements[i] - measurements[i - 1];
    if (duration != clock::duration() && duration < min_duration)
      min_duration = duration;
  }
  std::cout << min_duration;
}
Run Code Online (Sandbox Code Playgroud)

一些测量结果(可能因系统而异):

  • 在 godbolt 使用的 libstdc++ 和 Linux 上,这大约需要 20ns。

  • 在 libc++ 和 macOS 上,这大约需要 41 纳秒。

now请注意,对或 的初始调用clock_gettime几乎总是比后续调用慢,这可能是由于缓存或分支预测所致。