2008-08-23 53 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