1

プログラムで「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
4

2 に答える 2

3

目的は何ですか:

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

usec の最上位 3 桁が必要なようです。その場合、私が考えることができる最も簡単な方法は、usec を 1000 で割り、それで完了することです。

テストケース:

  • 999999 ⇒ 999
  • 99999 ⇒ 999 (本来は 099)
  • 9999 ⇒ 999 (本来は 009)
  • 999 ⇒ 999 (000 のはず)
于 2008-09-16T11:32:17.767 に答える
2

sec と usec の構成のどこかにおそらくバグがあると思います。表示されているエラーの種類を知らずに、正確に何を言うことはできません。大まかな推測では、usec が > 999999 になることはあり得ないため、いつ sec を調整するかを知るためにオーバーフローに依存しています。また、期間の出力形式に問題がある可能性もあります。

ともかく。出力時に独自の rusage を作成しようとするのではなく、utime および stime コンポーネントを float 秒として保存しないのはなぜですか? 以下は適切な秒数を与えると確信しています。

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 を使用できます。

于 2008-08-25T20:40:53.810 に答える