Question

J'essaie d'utiliser les statistiques « rusage » dans mon programme pour obtenir des données similaires à celles du temps outil.Cependant, je suis presque sûr de faire quelque chose de mal.Les valeurs semblent correctes mais peuvent parfois être un peu bizarres.Je n'ai pas trouvé de bonnes ressources en ligne.Est-ce que quelqu'un sait comment faire mieux ?

Désolé pour le code long.

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
Était-ce utile?

La solution

Quel est le but de :

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

Je suppose que vous voulez les trois chiffres les plus significatifs de l'usec ;dans ce cas, le moyen le plus simple auquel je puisse penser est de diviser usec par 1000, et d'en finir avec cela.

Cas de tests :

  • 999999 ⇒ 999
  • 99999 ⇒ 999 (devrait être 099)
  • 9999 ⇒ 999 (devrait être 009)
  • 999 ⇒ 999 (devrait être 000)

Autres conseils

Je pense qu'il y a probablement un bug quelque part dans votre composition de sec et usec.Je ne peux pas vraiment dire quoi exactement sans connaître les types d'erreurs que vous voyez.Une hypothèse approximative serait que usec ne peut jamais être > 999999, vous comptez donc sur le débordement pour savoir quand ajuster sec.Cela pourrait également être simplement un problème avec votre format de sortie de durée.

De toute façon.Pourquoi ne pas stocker les composants utime et stime sous forme de secondes flottantes plutôt que d'essayer de créer votre propre utilisation en sortie ?Je suis presque sûr que ce qui suit vous donnera les secondes nécessaires.

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 vous souhaitez décomposer cela en un rusage, vous pouvez toujours int-div et modulo.

@Chris :

Je suppose que vous voulez les trois chiffres les plus significatifs de l'usec

Oui.Le nombre total de chiffres dans usec varie et je veux réduire ceux en dessous de 1000.Par exemple, si usec=1000, je veux obtenir le résultat 100 (et non 1, comme vous le proposez).Je ne peux donc pas simplement diviser par 1000.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top