CpuTimer.h

00001 # ifndef CpuTimer_h
00002 # define CpuTimer_h CpuTimer_h
00003 
00004 # include "Root.h"  // parent
00005 
00006 # include <sys/time.h>
00007 # include <sys/resource.h>
00008 # include <iomanip>  // setw
00009 
00010 namespace Conjecture {
00011 
00012     // FUTURE FIX: Are these macros necessary?
00013 # define TIME_USAGE(usage) \
00014         struct rusage usage; \
00015         if ( getrusage(RUSAGE_SELF,&usage) != 0 ) { cerr << "ERROR: getrusage failed!" << endl; exit(1); }
00016     
00017 // end_usage   must be a 'struct rusage' variable
00018 // start_usage must be a 'struct rusage' variable
00019 // time must be a 'unsigned' variable
00020 # define TIME_USAGE_DIFF(end_usage, start_usage, time) \
00021                 time = \
00022                     ((now.ru_utime.tv_sec - start.ru_utime.tv_sec) * 1000000) + \
00023                     (now.ru_utime.tv_usec - start.ru_utime.tv_usec) + \
00024                     ((now.ru_stime.tv_sec - start.ru_stime.tv_sec) * 1000000) + \
00025                     (now.ru_stime.tv_usec - start.ru_stime.tv_usec); 
00026     
00027     // iters must be an unsigned number 
00028 # define TIME_START_ITERATION(iters) { \
00029                  TIME_USAGE(start); \
00030                  for ( unsigned __i = 0; __i < iters; ++__i )
00031  
00032 # define TIME_END_ITERATION(tdiff) \
00033                TIME_USAGE(now); \
00034                TIME_USAGE_DIFF(now, start, tdiff); \
00035             }
00036 
00037     
00038     /********************************************************************
00039      * \class CpuTimer
00040      *
00041      * \brief microsecond-level timing support
00042      *
00043      * Provides a microsecond level CPU usage timer, for user
00044      * time, system time, or a combination of both. See also the
00045      * WallTimer class.
00046      *
00047      * Standard usage is:
00048      *    using namespace Conjecture;
00049      *    CpuTimer timer;  // turned on when created.
00050      *    ... 
00051      *    cout << "Total microsecond used: " << timer.millitime() << endl;
00052      *
00053      * Features are:
00054      *    timer.stop();   // stop timing so subsequent timing requests all
00055      *                    // apply to the same time interval
00056      *    timer.start();  // restart the timer from now.
00057      *    timer.print();  // prints out a full summary
00058      *    timer.XtimeY(); // Returns time interval in request units X (seconds
00059      *                    // if X is empty, otherwise X = 'milli' or 'micro').
00060      *                    // Only returns the time for request cpu section Y
00061      *                    // (both if Y is empty, otherwise Y = 'System' or 'User').
00062      *
00063      **********************************************************************/
00064 
00065     class CpuTimer : public Root {
00066       public:
00067         // Types
00068 
00069         // Constructors/Destructors
00070         CpuTimer();
00071 
00072         // Accessors
00073         inline const bool &          running() const { return this->_running; }
00074         inline const struct rusage & reading() const { return this->_reading; }
00075         inline const struct rusage & start()   const { return this->_start; }
00076         
00077         // Input/Output
00078         
00079         // Interface
00080 
00085         void start();
00086 
00091         void stop();
00092 
00097         inline unsigned time()            const {return  read() / 1000000; }
00098 
00103         inline unsigned timeUser()        const { return readUser() / 1000000; }
00104 
00109         inline unsigned timeSystem()      const { return readSystem() / 1000000; }
00110 
00115         inline unsigned millitime()       const { return read() / 1000; }
00116 
00121         inline unsigned millitimeUser()   const { return readUser() / 1000; }
00122 
00127         inline unsigned millitimeSystem() const { return readSystem() / 1000; }
00128 
00133         inline unsigned microtime()       const { return read() ; }
00134 
00139         inline unsigned microtimeUser()   const { return readUser() ; }
00140 
00145         inline unsigned microtimeSystem() const { return readSystem() ; }
00146 
00151         void print(ostream & os = cout) const;
00152 
00157         void printSummary(ostream & os = cout) const;
00158         void printMilliSummary(ostream & os = cout) const;
00159         void printMicroSummary(ostream & os = cout) const;
00160 
00161         static void test(int argc = 0, const char* argv[] = NULL);
00162     
00163       protected:
00164         // Accessors
00165         inline void            runningIs(const bool & running) { this->_running = running; }
00166         inline void            readingIs(const struct rusage & reading) { this->_reading = reading; }
00167         inline void            startIs(const struct rusage & start) { this->_start = start; }
00168         
00169         // Methods 
00170         
00171       private: 
00172         // Accessors
00173         inline bool &          runningRef() { return this->_running; }
00174         inline struct rusage & readingRef() { return this->_reading; }
00175         inline struct rusage & startRef() { return this->_start; }
00176         
00177         // Methods 
00178 
00179         inline void getInfo( struct rusage & info ) const {
00180             if ( getrusage(RUSAGE_SELF,&info) != 0 ) {
00181                 cerr << "ERROR: getrusage failed!" << endl;
00182                 // Throw an exception instead of crashing!
00183                 exit(1);
00184             }
00185         }
00186 
00187         unsigned long read() const;
00188         unsigned long readUser() const;
00189         unsigned long readSystem() const;
00190         
00191         // State
00192         bool            _running;
00193         struct rusage   _reading;
00194         struct rusage   _start;
00195     };
00196 }
00197 
00198 # endif // CpuTimer_h
00199 

Generated on Wed Jun 14 15:08:02 2006 for Conjecture by  doxygen 1.4.6