为什么用getrusage()测得的用户时间是否接近完全一致?

时间:2016-11-10 18:01:52

标签: linux getrusage

这个C ++程序提供了可变的结果。有时变化很大。我打电话给getrusage()一次以获得开始时间。然后我在一个循环中调用rand()500000000次。然后我再次调用getrusage()并在两个getrusage()调用之间输出已用完的用户和系统时间。根据它包含的内容,我可以理解为什么“系统时间”不一致。但我希望“用户时间”是(主进程)线程处于运行状态的时间。我认为从一次奔跑到另一次奔跑都非常接近完全一致。但事实并非如此。

#include <iostream>
#include <exception>
#include <cstdlib>

#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>

using std::cout;

// tm is end time on intput, time different from start to end on output.
void since(const struct timeval start, struct timeval &tm)
  {
    if (tm.tv_sec == start.tv_sec)
      {
        tm.tv_sec = 0;
        tm.tv_usec -= start.tv_usec;
      }
    else
      {
        tm.tv_usec += 1000000 - start.tv_usec;
        tm.tv_sec -= start.tv_sec;
        if (tm.tv_usec >= 1000000)
          {
            tm.tv_usec -= 1000000;
            ++tm.tv_sec;
          }
      }
  }

void out_tm(const struct timeval &tm)
  {
    cout << "seconds: " << tm.tv_sec;
    cout << "  useconds: " << tm.tv_usec;
  }

void bail(const char *msg)
  {
    cout << msg << '\n';
    std::terminate();
  }

int main()
  {
    struct rusage usage;

    if (getrusage(RUSAGE_SELF, &usage))
      bail("FAIL:  getrusage() call failed");

    struct timeval user_tm = usage.ru_utime;
    struct timeval sys_tm = usage.ru_stime;

    for (unsigned i = 0; i < 500000000; ++i)
      std::rand();

    if (getrusage(RUSAGE_SELF, &usage))
      bail("FAIL:  getrusage() call failed");

    since(user_tm, usage.ru_utime);
    user_tm = usage.ru_utime;

    since(sys_tm, usage.ru_stime);
    sys_tm = usage.ru_stime;

    cout << "User time:  ";
    out_tm(user_tm);

    cout << "\nSystem time:  ";
    out_tm(sys_tm);
    cout << '\n';

    return(0);
  }

1 个答案:

答案 0 :(得分:0)

gnu推荐以下代码来衡量时差。

您的代码存在一些可能导致时间跳跃的差异,请尝试一下。

int
timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y)
{
  /* Perform the carry for the later subtraction by updating y. */
  if (x->tv_usec < y->tv_usec) {
    int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
    y->tv_usec -= 1000000 * nsec;
    y->tv_sec += nsec;
  }
  if (x->tv_usec - y->tv_usec > 1000000) {
    int nsec = (x->tv_usec - y->tv_usec) / 1000000;
    y->tv_usec += 1000000 * nsec;
    y->tv_sec -= nsec;
  }

  /* Compute the time remaining to wait.
     tv_usec is certainly positive. */
  result->tv_sec = x->tv_sec - y->tv_sec;
  result->tv_usec = x->tv_usec - y->tv_usec;

  /* Return 1 if result is negative. */
  return x->tv_sec < y->tv_sec;
}