Pregunta

Estoy intentando utilizar estadísticas de "rusage" en mi programa para obtener datos similares a los del tiempo herramienta.Sin embargo, estoy bastante seguro de que estoy haciendo algo mal.Los valores parecen correctos, pero a veces pueden ser un poco extraños.No encontré buenos recursos en línea.¿Alguien sabe cómo hacerlo mejor?

Perdón por el código largo.

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
¿Fue útil?

Solución

Cual es el proposito de:

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

Deduzco que quieres los tres dígitos más significativos del usec;en ese caso, la forma más sencilla que se me ocurre es dividir usec entre 1000 y listo.

Casos de prueba:

  • 999999 ⇒ 999
  • 99999 ⇒ 999 (debe ser 099)
  • 9999 ⇒ 999 (debe ser 009)
  • 999 ⇒ 999 (debe ser 000)

Otros consejos

Creo que probablemente haya un error en algún lugar de tu composición de sec y usec.Realmente no puedo decir exactamente qué sin saber los tipos de errores que estás viendo.Una suposición aproximada sería que usec nunca puede ser > 999999, por lo que depende del desbordamiento para saber cuándo ajustar sec.También podría ser simplemente un problema con el formato de salida de duración.

De todos modos.¿Por qué no almacenar los componentes utime y stime como segundos flotantes en lugar de intentar crear su propio rusage en la salida?Estoy bastante seguro de que lo siguiente le dará los segundos adecuados.

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);
}

Si quieres descomponer esto nuevamente en un rusage, siempre puedes int-div y módulo.

@Chris:

Supongo que quieres los tres dígitos más significativos del uso.

Sí.El número total de dígitos en usec varía y quiero reducir aquellos por debajo de 1000.Por ejemplo, si usec=1000, quiero obtener el resultado 100 (no 1, como propones).Por lo tanto, no puedo simplemente dividir entre 1000.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top