Статистика rusage

Я пытаюсь использовать статистику «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
23.08.2008 12:57:16
3 ОТВЕТА
РЕШЕНИЕ

Какова цель:

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

Я понимаю, что вы хотите три наиболее значимые цифры использования; в этом случае самый простой способ, который я могу придумать, - это разделить usec на 1000 и покончить с этим.

Тестовые случаи:

  • 999999 ⇒ 999
  • 99999 ⇒ 999 (должно быть 099)
  • 9999 ⇒ 999 (должно быть 009)
  • 999 ⇒ 999 (должно быть 000)
3
16.09.2008 11:32:17

Я думаю, что где-то в вашем составе sec и usec есть ошибка. Я не могу точно сказать, что именно, не зная, какие ошибки вы видите. Грубое предположение состоит в том, что usec никогда не может быть> 999999, поэтому вы полагаетесь на переполнение, чтобы знать, когда настраивать sec. Это также может быть проблема с выходным форматом продолжительности.

Так или иначе. Почему бы не хранить компоненты utime и stime в виде секунд с плавающей запятой вместо того, чтобы пытаться создать свой собственный вывод на выходе? Я уверен, что следующее даст вам подходящие секунды.

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.

2
27.08.2008 13:51:11

@Крис:

Я понимаю, что вы хотите три наиболее значимые цифры использования

Да. Общее число цифр usecменяется, и я хочу сократить их до 1000. Например, если usec=1000я хочу получить результат 100 (а не 1, как вы предлагаете). Поэтому я не могу просто разделить на 1000.

0
13.10.2008 09:36:13
Я не уверен, что вы подразумеваете под изменяющимся числом цифр. Насколько я знаю, все значения в нем должны быть между 0 и 999 999, что соответствует 0 мс и 999,999 мс соответственно. «Наиболее значимые три цифры» для меня означали, что вы хотели подсчитать миллисекунды. Я прочитал что-то не так?
Chris Jester-Young 18.09.2008 10:24:38
Крис, @ тег, похоже, не работает в любом случае. По поводу вашего комментария: я больше не работаю над этим кодом, и я больше не уверен, что именно я хотел получить. : - / AFAIR Я хотел вычислить 999 чисел в вашем ответе, то есть не те, которые вы указали как «должно быть». Теперь я думаю, что вы были правы.
Konrad Rudolph 13.10.2008 09:54:13