2008-08-23 107 views
1

我正在尝试在我的程序中使用“rusage”统计来获取与time工具类似的数据。但是,我很确定我做错了什么。这些价值似乎是正确的,但有时可能有点奇怪。我没有在网上找到好的资源。有人知道如何做得更好吗?“rusage”统计

对不起,长码。

class StopWatch { 
public: 
    void start() { 
     getrusage(RUSAGE_SELF, &m_begin); 
     gettimeofday(&m_tmbegin, 0); 
    } 

    void stop() { 
     getrusage(RUSAGE_SELF, &m_end); 
     gettimeofday(&m_tmend, 0); 
     timeval_sub(m_end.ru_utime, m_begin.ru_utime, m_diff.ru_utime); 
     timeval_sub(m_end.ru_stime, m_begin.ru_stime, m_diff.ru_stime); 
     timeval_sub(m_tmend, m_tmbegin, m_tmdiff); 
    } 

    void printf(std::ostream& out) const { 
     using namespace std; 

     timeval const& utime = m_diff.ru_utime; 
     timeval const& stime = m_diff.ru_stime; 

     format_time(out, utime); 
     out << "u "; 
     format_time(out, stime); 
     out << "s "; 
     format_time(out, m_tmdiff); 
    } 

private: 
    rusage m_begin; 
    rusage m_end; 
    rusage m_diff; 
    timeval m_tmbegin; 
    timeval m_tmend; 
    timeval m_tmdiff; 

    static void timeval_add(timeval const& a, timeval const& b, timeval& ret) { 
     ret.tv_usec = a.tv_usec + b.tv_usec; 
     ret.tv_sec = a.tv_sec + b.tv_sec; 
     if (ret.tv_usec > 999999) { 
      ret.tv_usec -= 1000000; 
      ++ret.tv_sec; 
     } 
    } 

    static void timeval_sub(timeval const& a, timeval const& b, timeval& ret) { 
     ret.tv_usec = a.tv_usec - b.tv_usec; 
     ret.tv_sec = a.tv_sec - b.tv_sec; 
     if (a.tv_usec < b.tv_usec) { 
      ret.tv_usec += 1000000; 
      --ret.tv_sec; 
     } 
    } 

    static void format_time(std::ostream& out, timeval const& tv) { 
     using namespace std; 
     long usec = tv.tv_usec; 
     while (usec >= 1000) 
      usec /= 10; 
     out << tv.tv_sec << '.' << setw(3) << setfill('0') << usec; 
    } 
}; // class StopWatch 

回答

3

是什么目的:

while (usec >= 1000) 
    usec /= 10; 

我收集所需的微秒的最显著三位;在这种情况下,我能想到的最直接的方式就是将usec除以1000,然后完成。

测试用例:

  • 999999⇒999
  • 99999⇒999(应为099)
  • 9999⇒999(应为009)
  • 999⇒999(应为000)
2

我觉得在sec和usec的组合中可能存在一个bug。如果不知道你所看到的错误种类,我无法确切地说出。一个粗略的猜测是,usec永远不会> 999999,所以你依靠溢出来知道什么时候调整sec。这也可能只是您的持续时间输出格式的问题。

无论如何。为什么不把utime和stime组件存储为浮点数而不是试图在输出上构建自己的rusage?我很确定以下几点会给你适当的秒数。

static int timeval_diff_ms(timeval const& end, timeval const& start) { 
    int micro_seconds = (end.tv_sec - start.tv_sec) * 1000000 
     + end.tv_usec - start.tv_usec; 

    return micro_seconds; 
} 

static float timeval_diff(timeval const& end, timeval const& start) { 
    return (timeval_diff_ms(end, start)/1000000.0f); 
} 

如果你想把这个分解成一个rusage,你总是可以int-div和modulo。

0

@克里斯:

我收集你想使用的最重要的三位数字

是的。 usec中的位数总数有所不同,我希望将这些位数减少到1000以下。例如,如果usec=1000,我想要得到结果100(不是1,如您所建议的那样)。因此,我不能简单地除以1000.

+0

我不确定你的意思是不同的usec位数。据我所知,其中的所有值都是在0到999,999之间,分别对应0 ms和999.999 ms。 “最重要的三位数字”对我来说意味着你想要毫秒数。我看错了吗? – 2008-09-18 10:24:38