为什么gettimeofday()间隔偶尔会消极?

And*_*ack 5 c c++ linux timing gettimeofday

我有一个实验性的库,我试图测量它的性能.为此,我写了以下内容:

struct timeval begin;
gettimeofday(&begin, NULL);
{
    // Experiment!
}
struct timeval end;
gettimeofday(&end, NULL);

// Print the time it took!
std::cout << "Time: " << 100000 * (end.tv_sec - begin.tv_sec) + (end.tv_usec - begin.tv_usec) << std::endl;
Run Code Online (Sandbox Code Playgroud)

偶尔,我的结果包括负面时间,其中一些是荒谬的.例如:

Time: 226762
Time: 220222
Time: 210883
Time: -688976
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

Mic*_*Ulm 6

你有一个错字.更正了最后一行(注意0的数量):

std::cout << "Time: " << 1000000 * (end.tv_sec - begin.tv_sec) + (end.tv_usec - begin.tv_usec) << std::endl;
Run Code Online (Sandbox Code Playgroud)

BTW,timersub是一种内置方法,可以获得两个时间间隔的差异.

  • 为什么这被认为是答案?它不正确,它只是修复了时间呈现中的一个小错误.它没有解决为什么负面时期出现的核心问题.读者注意 - 这不是一个有效的答案! (5认同)
  • 所以基本上,你需要将一个大脑应用于错误以深入理解它,但几乎......它仍然回答了这个问题.:) (3认同)

def*_*ode 5

posix 实时库更适合测量高精度间隔。您真的不想知道当前时间。您只想知道两点之间相隔多长时间。这就是单调时钟的用途。

struct timespec begin;
clock_gettime( CLOCK_MONOTONIC, &begin );
{
    // Experiment!
}
struct timespec end;
clock_gettime(CLOCK_MONOTONIC, &end );

// Print the time it took!
std::cout << "Time: " << double(end.tv_sec - begin.tv_sec) + (end.tv_nsec - begin.tv_nsec)/1000000000.0 << std::endl;
Run Code Online (Sandbox Code Playgroud)

链接时需要添加-lrt.

使用单调时钟有几个优点。它通常使用硬件定时器(Hz 晶体或其他),因此它通常比gettimeofday(). 即使 ntpd 或用户误玩系统时间,单调计时器也保证永远不会倒退。


cod*_*rio 5

您处理了负值,但它仍然不正确。毫秒变量之间的差异是错误的,假设我们的开始时间和结束时间分别为 1.100 秒和 2.051 秒。根据接受的答案,这将是 1.049 秒的运行时间,这是不正确的。

下面的代码处理只有毫秒差异但没有秒差异的情况以及毫秒值溢出的情况。

if(end.tv_sec==begin.tv_sec)
printf("Total Time =%ldus\n",(end.tv_usec-begin.tv_usec));
else
printf("Total Time =%ldus\n",(end.tv_sec-begin.tv_sec-1)*1000000+(1000000-begin.tv_usec)+end.tv_usec);
Run Code Online (Sandbox Code Playgroud)