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

时间:2015-11-27 12:53:30

标签: 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>
}

,输出为:

chrono 0.998352 (ms): 
gettimeofday: 999
clock 0.544922 (ms)

为何与众不同?我希望时钟至少与其他时钟一样大,不是吗?

2 个答案:

答案 0 :(得分:4)

  

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();

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

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

进行测试

答案 1 :(得分:1)

使用std::chrono来衡量执行时间的简单方法是:

auto start = high_resolution_clock::now();

/*
* multiple iterations of the code you want to benchmark - 
* make sure the optimizer doesn't eliminate the whole code
*/

auto end = high_resolution_clock::now();

std::cout << "Execution time (us): " << duration_cast<microseconds>(end - start).count() << std::endl;