Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用rusage的进程/线程不可能的Cpu时间_C++_C_Linux_Multithreading_Ace - Fatal编程技术网

C++ 使用rusage的进程/线程不可能的Cpu时间

C++ 使用rusage的进程/线程不可能的Cpu时间,c++,c,linux,multithreading,ace,C++,C,Linux,Multithreading,Ace,我正在计算进程/线程正在使用的cpu时间与调用某个函数之间的增量 我得到了进程cpu时间的不可能值,下一次调用返回的cpu时间更小,这是不可能的 这是我用来计算cpu时间的代码: u64 CpuTime::calculateCpuTime(bool a_thread) { struct rusage l_rusage; int retVal; if(a_thread) { retVal = getrusage(1, &l_rusage)

我正在计算进程/线程正在使用的cpu时间与调用某个函数之间的增量

我得到了进程cpu时间的不可能值,下一次调用返回的cpu时间更小,这是不可能的

这是我用来计算cpu时间的代码:

  u64 CpuTime::calculateCpuTime(bool a_thread)
  {
    struct rusage l_rusage;
    int retVal;
    if(a_thread)
    {
      retVal = getrusage(1, &l_rusage); //1 = RUSAGE_THREAD
    }
    else
    {
      retVal = getrusage(0, &l_rusage); //0 = RUSAGE_SELF
    }
    ASSERT(retVal==0);

    u64 userUSeconds = (static_cast<u64>(l_rusage.ru_utime.tv_sec)*1000000)+
      (static_cast<u64>(l_rusage.ru_utime.tv_usec));

    u64 systemUSeconds = (static_cast<u64>(l_rusage.ru_stime.tv_sec)*1000000)+
      (static_cast<u64>(l_rusage.ru_stime.tv_usec));

    if(a_thread)
    {
      return userUSeconds + systemUSeconds;
    }
    return (userUSeconds + systemUSeconds) / ACE_OS::num_processors_online();
  }
执行系统调用的对象(“m_cpuTime”)是一个受互斥体保护的单线程,一次只能有一个线程访问它

它保存线程cpu使用情况的映射m_threadsCpuMap(用于增量),以及最后一个进程cpu使用情况m_processCpu

另一编辑:

我用一个简单的测试简化了它,使用一个线程,去掉了活动cpu的除法,并且只检查进程cpu时间,仍然有不可能的结果

以下是更新后的功能:

测试:

我使用ACE_OS实现可移植性,但它可以与sys/time.h中的默认函数一起工作


但是,我仍然对rusage奇怪的行为有疑问,是什么导致它给出这些值。

仔细检查以下几行:您将系统时间秒乘以10万,而不是100万:

u64 userUSeconds = (static_cast<u64>(l_rusage.ru_utime.tv_sec)*1000000)+
  (static_cast<u64>(l_rusage.ru_utime.tv_usec));

u64 systemUSeconds = (static_cast<u64>(l_rusage.ru_stime.tv_sec)*100000)+
  (static_cast<u64>(l_rusage.ru_stime.tv_usec));

也就是-900000(0.9秒)+1000 us

我注意到,在系统时间计算中,您没有应用相同的数学来计算用户和系统时间(缺少*100000)。我将添加其余部分,希望将其缩短一点。关于*1000000,r_使用时间以秒为单位,r_时间以微秒为单位,当我以微秒为单位返回值时,我只需要乘以秒数,收集4个不同的值,同时获取/释放锁可能是问题的根源,任何线程都可能启动并延迟当前线程的执行。这对你来说可能是个问题,也可能不是问题,一旦你收集了这些值,我就没有深入了解你在做什么:-如果你没有向我们展示真正的代码,有点难以帮助你,哈哈。你的map m_threadsCpuMap对象是什么类型的。我看到您获得了对其中值的引用,并假设它是映射中的实际值,因此当它得到更新时,您不需要在映射中重新设置值。。这是一个有效的假设吗?它可能会将副本返回给您,而您正在引用/更新副本而不是原始副本?或者它是一个简单的数组:)?谢谢你,不敢相信我真的错过了,它总是最简单的错误。
  u64 CpuTime::getThreadDeltaCpuTime()
  {
    pid_t thisThread = (pid_t) syscall (SYS_gettid);
    u64& val = m_threadsCpuMap[thisThread];
    u64 oldValue =val;
    val = calculateCpuTime(true);
    return val - oldValue;
  }

  u64 CpuTime::getProcessDeltaCpuTime()
  {
    u64 oldValue = m_processCpu;
    m_processCpu = calculateCpuTime(false);

    return m_processCpu - oldValue;
  }

  u64 getThreadCpuTime()
  {
    return CpuTime::calculateCpuTime(true);
  }

  u64 getProcessCpuTime()
  {
    return CpuTime::calculateCpuTime(false);
  }
for(int i = 0; i < 100000 ; i++)
{
  for(int k = 0; k < 1000000; k++)
    m = k % i;
    cpuTime = CpuTime::instance()->getProcessDeltaCpuTime();
}
  u64 CpuTime::getProcessDeltaCpuTime()
  {
    u64 oldValue = m_processCpu;
    m_processCpu = calculateCpuTime(eThisProcess);
   Log<<value(oldValue)<<value(m_processCpu)<value( m_processCpu - oldValue)<<endlog;
    return m_processCpu - oldValue;
  }

  u64 CpuTime::calculateCpuTime(int a_type)
  {
    struct rusage l_rusage;
    int retVal;
    if(a_type == eThisThread)
    {
      retVal = /*ACE_OS::*/getrusage(1, &l_rusage);
    }
    else
    {
      retVal = /*ACE_OS::*/getrusage(0, &l_rusage);
    }

    u64 userUSeconds = (static_cast<u64>(l_rusage.ru_utime.tv_sec)*1000000)+
      (static_cast<u64>(l_rusage.ru_utime.tv_usec));

    u64 systemUSeconds = (static_cast<u64>(l_rusage.ru_stime.tv_sec)*100000)+
      (static_cast<u64>(l_rusage.ru_stime.tv_usec));

    if(a_type == eThisThread)
    {
      return userUSeconds + systemUSeconds;
    }
    return (userUSeconds + systemUSeconds)/* / ACE_OS::num_processors_online()*/;
int main()
{
  long int n = 0;
  long int oldValue = 0;
  long int newValue = 0;
  unsigned long int deltaValue = 0;

  for(int i = 0; i < 1000000; i++)
  {
    for(long int m = 0; m <10000; m++)
      n = m + i;
    struct rusage l_rusage;
    int retVal;
    retVal = getrusage(0, &l_rusage);
    if(retVal != 0) return 0;

    long int userUSeconds = l_rusage.ru_utime.tv_sec*1000000 + l_rusage.ru_utime.tv_usec;

    long int systemUSeconds = l_rusage.ru_stime.tv_sec*100000 + l_rusage.ru_stime.tv_usec;
    oldValue = newValue;
    newValue = userUSeconds + systemUSeconds;
    deltaValue = newValue - oldValue;
    if(deltaValue != 0)
      std::cout<<"Old value: "<< oldValue <<" New Value: "<< newValue <<" Delta value: "<<deltaValue<<"\n";


  }
  std::cout<<n;
  return 0;
}
  u64 CpuMeasure::calculateCpuTime(int a_type)
  {
    struct timespec ts;

    if(a_type == eThisThread)
    {
      if (ACE_OS::clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0)
      {
         return (u64)ts.tv_sec * 1000000 + (u64)ts.tv_nsec / 1000; //From nano to mili seconds
      }
    }
    else
    {
      if (ACE_OS::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0)
      {
         return (u64)ts.tv_sec * 1000000 + (u64)ts.tv_nsec / 1000;
      }
    }
    ASSERT(false); //we cant be here, unless some thing bad happened
    return 0;
}
u64 userUSeconds = (static_cast<u64>(l_rusage.ru_utime.tv_sec)*1000000)+
  (static_cast<u64>(l_rusage.ru_utime.tv_usec));

u64 systemUSeconds = (static_cast<u64>(l_rusage.ru_stime.tv_sec)*100000)+
  (static_cast<u64>(l_rusage.ru_stime.tv_usec));
 18446744073708652615 - 2^64 + 1 = -899000