测量执行时间 - gettimeofday 与 clock() 与 chrono

cau*_*chy 1 c++ c++11

我有一个应该每毫秒执行一次的子程序。我想检查一下确实是这样。但是我从不同的函数得到不同的执行时间。我一直试图了解这些函数之间的差异(关于这个主题有几个 SO 问题),但我无法理解我得到的结果。请忘记全局变量等。这是一个遗留代码,用 C 编写,移植到 C++,我正在努力改进,所以很乱。

< header stuff>
std::chrono::high_resolution_clock::time_point tchrono;
int64_t tgettime;
float tclock;

void myfunction(){

<all kinds of calculations>

  using ms = std::chrono::duration<double, std::milli>;
  std::chrono::high_resolution_clock::time_point tmpchrono = std::chrono::high_resolution_clock::now();
  printf("chrono %f (ms): \n",std::chrono::duration_cast<ms>(tmpchrono-tchrono).count());
  tchrono = tmpchrono;

  struct timeval tv;
  gettimeofday (&tv, NULL);
  int64_t tmpgettime = (int64_t) tv.tv_sec * 1000000 + tv.tv_usec;
  printf("gettimeofday: %lld\n",tmpgettime-tgettime);
  tgettime = tmpgettime;

  float tmpclock = 1000.0f*((float)clock())/CLOCKS_PER_SEC;
  printf("clock %f (ms)\n",tmpclock-tclock);
  tclock = tmpclock;

  <more stuff>
}
Run Code Online (Sandbox Code Playgroud)

输出是:

chrono 0.998352 (ms): 
gettimeofday: 999
clock 0.544922 (ms)
Run Code Online (Sandbox Code Playgroud)

为什么会有差异?我希望时钟至少与其他时钟一样大,或者不是?

eer*_*ika 6

std::chrono::high_resolution_clock::now() 甚至不起作用。

std::chrono::milliseconds将毫秒表示为整数。当您转换为该表示时,更高粒度的时间表示将被截断为整毫秒。然后将其分配给具有double表示和秒比的持续时间。然后你将duration对象 - 而不是double- 传递给printf。所有这些步骤都是错误的。

要将毫秒作为浮点数,请执行以下操作:

using ms = std::chrono::duration<double, std::milli>;
std::chrono::duration_cast<ms>(tmpchrono-tchrono).count();
Run Code Online (Sandbox Code Playgroud)

clock()返回进程使用的处理器时间。这将取决于操作系统调度程序为您的进程提供了多少时间。除非该进程是系统上唯一的进程,否则这将与通过的挂钟时间不同。

gettimeofday()返回挂钟时间。

使用 high_resolution_clock::now() 和 gettimeofday() 有什么区别?

两者都测量挂钟时间。两者的内部表示都是实现定义的。两者的粒度也是实现定义的。

gettimeofday是 POSIX 标准的一部分,因此可用于所有符合该标准 (POSIX.1-2001) 的操作系统。gettimeofday不是单调的,即它会受到诸如设置时间(由 ntpd 或由管理员)和夏令时更改等因素的影响。

high_resolution_clock表示由实现提供的具有最小滴答周期的时钟。它可能是 std::chrono::system_clock 或 std::chrono::steady_clock 的别名,或第三个独立时钟。

high_resolution_clock是 c++ 标准库的一部分,因此可用于所有符合该标准 (c++11) 的编译器。high_resolution_clock可能是也可能不是单调的。这可以用high_resolution_clock::is_steady