2008-08-23 7 views
1

J'essaie d'utiliser les statistiques "rusage" dans mon programme pour obtenir des données similaires à celles de l'outil time. Cependant, je suis assez sûr que je fais quelque chose de mal. Les valeurs semblent à peu près 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 le faire mieux?"rusage" statistics

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 

Répondre

3

Quel est le but de:

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

Je suppose que vous voulez que les trois chiffres les plus significatifs de la microseconde; dans ce cas, la façon la plus directe que je puisse penser est de diviser usec par 1000, et être fait avec cela.

cas de test:

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

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

Quoi qu'il en soit. Pourquoi ne pas stocker les composants utime et stime en secondes flottantes plutôt qu'en essayant de construire votre propre rusage en sortie? Je suis sûr que ce qui suit vous donnera les bonnes secondes.

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

0

: @ 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 inférieurs à 1000. Par exemple, si usec=1000, je veux obtenir le résultat 100 (pas 1, comme vous le proposez). Par conséquent, je ne peux pas simplement diviser par 1000.

+0

Je ne suis pas sûr de ce que vous voulez dire par le nombre de chiffres en usec variant. Pour autant que je sache, toutes les valeurs sont comprises entre 0 et 999.999, correspondant respectivement à 0 ms et 999.999 ms. "Les trois chiffres les plus significatifs" signifiaient que vous vouliez le nombre de millisecondes. Ai-je lu quelque chose de mal? –

+0

Chris, le @ tag ne semble pas fonctionner de toute façon. A propos de votre commentaire: Je ne travaille plus sur ce code et je ne sais plus exactement ce que je voulais obtenir. : -/AFAIR Je voulais calculer les nombres 999 dans votre réponse, c'est-à-dire * pas * ceux que vous avez listés comme "devraient être". Je pense maintenant que tu avais raison. –

Questions connexes