alpar@428: // -*- c++ -*- alpar@428: #ifndef HUGO_TIME_MEASURE_H alpar@428: #define HUGO_TIME_MEASURE_H alpar@428: klao@491: ///\ingroup misc alpar@428: ///\file alpar@428: ///\brief Tools for measuring cpu usage alpar@428: alpar@428: #include alpar@428: #include alpar@428: #include alpar@428: #include alpar@428: #include alpar@428: alpar@428: namespace hugo { alpar@428: alpar@428: /// \addtogroup misc alpar@428: /// @{ alpar@428: alpar@428: /// A class to store (cpu)time instances. alpar@428: alpar@428: /// This class stores five time values. alpar@428: /// - a real time alpar@428: /// - a user cpu time alpar@428: /// - a system cpu time alpar@428: /// - a user cpu time of children alpar@428: /// - a system cpu time of children alpar@428: /// alpar@428: /// TimeStamp's can be added to or substracted from each other and alpar@428: /// they can be pushed to a stream. alpar@458: /// alpar@458: /// In most cases, perhaps \ref Timer class is what you want to use instead. alpar@458: /// alpar@458: ///\author Alpar Juttner alpar@428: alpar@428: class TimeStamp alpar@428: { alpar@428: tms ts; alpar@428: double real_time; alpar@428: alpar@428: public: alpar@428: alpar@428: tms &getTms() {return ts;} alpar@428: const tms &getTms() const {return ts;} alpar@428: ///Read the current time values of the process alpar@428: void stamp() alpar@428: { alpar@428: timeval tv; alpar@428: times(&ts); alpar@428: gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6; alpar@428: } alpar@428: alpar@428: /// Constructor initializing with zero alpar@428: TimeStamp() alpar@428: { ts.tms_utime=ts.tms_stime=ts.tms_cutime=ts.tms_cstime=0; real_time=0;} alpar@428: ///Constructor initializing with the current time values of the process alpar@428: TimeStamp(void *) { stamp();} alpar@428: alpar@428: /// alpar@428: TimeStamp &operator+=(const TimeStamp &b) alpar@428: { alpar@428: ts.tms_utime+=b.ts.tms_utime; alpar@428: ts.tms_stime+=b.ts.tms_stime; alpar@428: ts.tms_cutime+=b.ts.tms_cutime; alpar@428: ts.tms_cstime+=b.ts.tms_cstime; alpar@428: real_time+=b.real_time; alpar@428: return *this; alpar@428: } alpar@428: /// alpar@428: TimeStamp operator+(const TimeStamp &b) const alpar@428: { alpar@428: TimeStamp t(*this); alpar@428: return t+=b; alpar@428: } alpar@428: /// alpar@428: TimeStamp &operator-=(const TimeStamp &b) alpar@428: { alpar@428: ts.tms_utime-=b.ts.tms_utime; alpar@428: ts.tms_stime-=b.ts.tms_stime; alpar@428: ts.tms_cutime-=b.ts.tms_cutime; alpar@428: ts.tms_cstime-=b.ts.tms_cstime; alpar@428: real_time-=b.real_time; alpar@428: return *this; alpar@428: } alpar@428: /// alpar@428: TimeStamp operator-(const TimeStamp &b) const alpar@428: { alpar@428: TimeStamp t(*this); alpar@428: return t-=b; alpar@428: } alpar@428: alpar@428: ///The time ellapsed since the last call of stamp() alpar@428: TimeStamp ellapsed() const alpar@428: { alpar@428: TimeStamp t(NULL); alpar@428: return t-*this; alpar@428: } alpar@428: alpar@428: friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t); alpar@428: alpar@428: ///Gives back the user time of the process alpar@428: double getUserTime() const alpar@428: { alpar@428: return double(ts.tms_utime)/sysconf(_SC_CLK_TCK); alpar@428: } alpar@428: ///Gives back the system time of the process alpar@428: double getSystemTime() const alpar@428: { alpar@428: return double(ts.tms_stime)/sysconf(_SC_CLK_TCK); alpar@428: } alpar@428: ///Gives back the user time of the process' children alpar@428: double getCUserTime() const alpar@428: { alpar@428: return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK); alpar@428: } alpar@428: ///Gives back the user time of the process' children alpar@428: double getCSystemTime() const alpar@428: { alpar@428: return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK); alpar@428: } alpar@428: ///Gives back the real time of the process alpar@428: double getRealTime() const {return real_time;} alpar@428: }; alpar@428: alpar@428: ///Class measuring the cpu time and real time usage of the process alpar@458: alpar@458: ///Class measuring the cpu time and real time usage of the process. alpar@458: ///It is quite easy-to-use, here is a short example. alpar@458: ///\code alpar@458: ///int main() alpar@458: ///{ alpar@458: /// alpar@458: /// ... alpar@458: /// alpar@458: /// Timer T(); alpar@458: /// doSomething(); alpar@458: /// cout << T; alpar@458: /// T.reset(); alpar@458: /// doSomethingElse(); alpar@458: /// cout << T; alpar@458: /// alpar@458: /// ... alpar@458: /// alpar@458: ///} alpar@458: ///\endcode alpar@458: /// alpar@458: ///\todo This shouldn't be Unix (Linux) specific. alpar@458: /// alpar@458: ///\author Alpar Juttner alpar@428: class Timer alpar@428: { alpar@428: TimeStamp start_time; alpar@428: alpar@428: void _reset() {start_time.stamp();} alpar@428: alpar@428: public: alpar@428: ///Constructor. It starts with zero time counters alpar@428: Timer() {_reset();} alpar@428: alpar@428: ///Computes the ellapsed time alpar@428: alpar@428: ///This conversion computes the ellapsed time alpar@428: ///since the construction of \c t or since alpar@428: ///the last \c t.reset(). alpar@428: operator TimeStamp () alpar@428: { alpar@428: TimeStamp t; alpar@428: t.stamp(); alpar@428: return t-start_time; alpar@428: } alpar@428: alpar@428: ///Resets the time counters alpar@428: TimeStamp reset() alpar@428: { alpar@428: TimeStamp t(start_time); alpar@428: _reset(); alpar@428: return start_time-t; alpar@428: } alpar@428: }; alpar@428: alpar@428: ///Prints the time counters alpar@428: alpar@428: ///Prints the time counters in the folloing form: alpar@428: /// alpar@440: /// u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs alpar@428: /// alpar@428: /// where the values are the alpar@440: /// \li \c u: user cpu time, alpar@440: /// \li \c s: system cpu time, alpar@440: /// \li \c cu: user cpu time of children, alpar@440: /// \li \c cs: system cpu time of children, alpar@440: /// \li \c real: real time. alpar@428: inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t) alpar@428: { alpar@428: long cls = sysconf(_SC_CLK_TCK); alpar@428: os << "u: " << double(t.getTms().tms_utime)/cls << alpar@428: "s, s: " << double(t.getTms().tms_stime)/cls << alpar@428: "s, cu: " << double(t.getTms().tms_cutime)/cls << alpar@428: "s, cs: " << double(t.getTms().tms_cstime)/cls << alpar@428: "s, real: " << t.getRealTime() << "s"; alpar@428: return os; alpar@428: } alpar@428: alpar@428: /// @} alpar@428: alpar@428: } //namespace hugo alpar@428: alpar@428: #endif //HUGO_TIME_MEASURE_H