// --------------------------------------------------------------------------- // class PERFTIMER definition // --------------------------------------------------------------------------- #ifndef DUMMY_TIMER /** Very accurate Timer class for benchmarking on SGI systems. This timer can be used to accurately take measurements on all SGI-systems, usually in the microseconds range. Note: getting the time on an unavailable Timer returns garbage. */ class PERFTIMER { private: static TIMEVAL_T frequency; static bool isinitialized; static bool available; public: // public for macro versions of Entry/Exit TIMEVAL_T start_count; TIMEVAL_T total_count; public: // this retrieves the timer frequency - will be called by constructor // NOTE: allow this to be called externally, so logging can be enabled! static void InitClass(bool verbose); /// the time type used for Perftimers typedef double t_time; /// returns the frequency static double GetFrequency(bool verbose = false); /// Constructor calls Start PERFTIMER(bool verbose = false); /// use in conjunction with Exit() to time parts of code that are called more than once void Entry(); /// stop counting but remember total void Exit(); /// read total time elapsed and reset the time - to be used with Entry()/Exit() double TotalTime(); /// reset and start the counter - use for timing one piece of code (implicit Entry()) void Start(); /** returns elapsed time in seconds - if restart is true, timer is also restarted - use with Start() (implicit Exit()/Entry() with same timestamp, with restart: implicit Exit()/TotalTime()/Entry()) */ double Elapsed(bool restart = true); /** returns elapsed time in milliseconds - if restart is true, timer is also restarted - use with Start() (implicit Exit()/Entry() with same timestamp, with restart: implicit Exit()/TotalTime()/Entry()) */ double Elapsedms(bool restart = true); // returns elapsed time in cycles - if restart is true, timer is also restarted //unsigned int ElapsedCycles(bool restart = true); /// false if no appropriate hardware found bool Available(); }; // --------------------------------------------------------------------------- // class PERFTIMER inline implementation // --------------------------------------------------------------------------- PERFTIMER_INLINE bool PERFTIMER::Available() { /// HACK: no SGI detection! return available; } // macro version to ensure inlining #define PERF_ENTRY(perftimer) TIMEVAL_GET((perftimer).start_count); PERFTIMER_INLINE void PERFTIMER::Entry() { TIMEVAL_GET(start_count); } PERFTIMER_INLINE void PERFTIMER::Start() { TIMEVAL_ZERO(total_count); Entry(); } // macro version to ensure inlining #define PERF_EXIT(perftimer) { TIMEVAL_T end_count; TIMEVAL_GET(end_count); TIMEVAL_ADD((perftimer).total_count, end_count, (perftimer).start_count);} PERFTIMER_INLINE void PERFTIMER::Exit() { TIMEVAL_T end_count; TIMEVAL_GET(end_count); TIMEVAL_ADD(total_count, end_count, start_count); } PERFTIMER_INLINE double PERFTIMER::TotalTime() { double time = TIMEVAL_TODOUBLE(total_count); TIMEVAL_ZERO(total_count); return time; } // returns elapsed time in seconds - if restart is true, timer is also restarted PERFTIMER_INLINE double PERFTIMER::Elapsed(bool restart) { TIMEVAL_T end_count; TIMEVAL_GET(end_count); TIMEVAL_ADD(total_count, end_count, start_count); TIMEVAL_ASSIGN(start_count, end_count); // unnecessary for entry/exit operation, but doesn't hurt double time = TIMEVAL_TODOUBLE(total_count); if (restart) { TIMEVAL_ZERO(total_count); } return time; } // returns elapsed time in milliseconds - if restart is true, timer is also restarted PERFTIMER_INLINE double PERFTIMER::Elapsedms(bool restart) { TIMEVAL_T end_count; TIMEVAL_GET(end_count); TIMEVAL_ADD(total_count, end_count, start_count); TIMEVAL_ASSIGN(start_count, end_count); // unnecessary for entry/exit operation, but doesn't hurt double time = TIMEVAL_TODOUBLE(total_count); if (restart) { TIMEVAL_ZERO(total_count); } return time * 1000.; } // Constructor calls Start PERFTIMER_INLINE PERFTIMER::PERFTIMER(bool verbose) { if (!isinitialized) InitClass(verbose); //TIMEVAL_ZERO(total_count); Start(); } #else class PERFTIMER { public: PERFTIMER(bool x = false) {} static double GetFrequency(bool) {return 1;} void Start() {} double Elapsed(bool restart = true) { return 0; } double Elapsedms(bool restart = true) { return 0; } void Entry() {} void Exit() {} double TotalCount() { return 0; } bool Available() { return false; } }; #endif