timer.hxx
Go to the documentation of this file.00001 #pragma once
00002 #ifndef OPENGM_TIMER_HXX
00003 #define OPENGM_TIMER_HXX
00004
00005 #include <stdexcept>
00006
00007 # if (defined(_OPENGM_TIMER_MACH__) || defined(__APPLE__))
00008 # define OPENGM_TIMER_MAC
00009 # elif (defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(_WIN64))
00010 # define OPENGM_TIMER_WINDOWS
00011 # ifndef WIN32_LEAN_AND_MEAN
00012 # define WIN32_LEAN_AND_MEAN
00013 # endif
00014 # endif
00015
00016 # if defined(OPENGM_TIMER_MAC)
00017 # include <mach/mach_time.h>
00018 # elif defined(OPENGM_TIMER_WINDOWS)
00019 # include <windows.h>
00020 # undef min
00021 # undef max
00022 # else
00023 # include <time.h>
00024 # endif
00025
00026 namespace opengm {
00027
00029 class Timer {
00030 public:
00031
00032 Timer();
00033
00034
00035 double elapsedTime() const;
00036
00037
00038 void tic();
00039 void toc();
00040 void reset();
00041
00042 private:
00043 #if defined(OPENGM_TIMER_MAC)
00044 typedef uint64_t TimerT;
00045 typedef double TimerC;
00046 #elif defined(OPENGM_TIMER_WINDOWS)
00047 typedef LONGLONG TimerT;
00048 typedef LARGE_INTEGER TimerC;
00049 #else
00050 typedef double TimerT;
00051 typedef timespec TimerC;
00052 #endif
00053
00054 TimerT start_;
00055 TimerC ts_;
00056 double duration_;
00057 double conversionFactor_;
00058 double elapsedTime_;
00059 };
00060
00062 template<class FUNCTOR>
00063 class Timing {
00064 public:
00065 typedef FUNCTOR Functor;
00066
00067 Timing(Functor, const size_t = 1);
00068 const std::vector<double>& times() const;
00069
00070 private:
00071 Functor functor_;
00072 std::vector<double> times_;
00073 };
00074
00075 inline Timer::Timer()
00076 : start_(0), duration_(0), elapsedTime_(0)
00077 {
00078 #if defined(OPENGM_TIMER_MAC)
00079 mach_timebase_info_data_t info;
00080 mach_timebase_info(&info);
00081 conversionFactor_ = (static_cast<double>(info.numer))/
00082 (static_cast<double>(info.denom));
00083 conversionFactor_ = conversionFactor_*1.0e-9;
00084 #elif defined(OPENGM_TIMER_WINDOWS)
00085 TimerC freq;
00086 QueryPerformanceFrequency(&freq);
00087 conversionFactor_ = 1.0/(static_cast<double>(freq.QuadPart));
00088 #else
00089 conversionFactor_ = 1.0;
00090 #endif
00091 reset();
00092 }
00093
00094 inline void Timer::tic() {
00095 #if defined(OPENGM_TIMER_MAC)
00096 start_ = mach_absolute_time();
00097 #elif defined(OPENGM_TIMER_WINDOWS)
00098 QueryPerformanceCounter(&ts_);
00099 start_ = ts_.QuadPart;
00100 #else
00101 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_);
00102 start_ = static_cast<double>(ts_.tv_sec) + 1.0e-9 *
00103 static_cast<double>(ts_.tv_nsec);
00104 #endif
00105 }
00106
00107 inline void Timer::toc() {
00108 #if defined(OPENGM_TIMER_MAC)
00109 duration_ = static_cast<double>(mach_absolute_time() - start_);
00110 #elif defined(OPENGM_TIMER_WINDOWS)
00111 LARGE_INTEGER qpc_t;
00112 QueryPerformanceCounter(&qpc_t);
00113 duration_ = static_cast<double>(qpc_t.QuadPart - start_);
00114 #else
00115 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_);
00116 duration_ = (static_cast<double>(ts_.tv_sec) + 1.0e-9 *
00117 static_cast<double>(ts_.tv_nsec)) - start_;
00118 #endif
00119 elapsedTime_ = duration_*conversionFactor_;
00120 }
00121
00122 inline void Timer::reset() {
00123 start_ = 0;
00124 duration_ = 0;
00125 elapsedTime_ = 0;
00126 }
00127
00128 inline double Timer::elapsedTime() const {
00129 return elapsedTime_;
00130 }
00131
00132 template<class FUNCTOR>
00133 inline Timing<FUNCTOR>::Timing(
00134 FUNCTOR functor,
00135 const size_t repetitions
00136 )
00137 : functor_(functor),
00138 times_(std::vector<double>())
00139 {
00140 if(repetitions < 1) {
00141 throw std::runtime_error("The number of repetition must be at least 1.");
00142 }
00143 for(size_t j=0; j<repetitions; ++j) {
00144 opengm::Timer timer;
00145 timer.tic();
00146 functor_();
00147 timer.toc();
00148 times_.push_back(timer.elapsedTime());
00149 }
00150 }
00151
00152 template<class FUNCTOR>
00153 inline const std::vector<double>&
00154 Timing<FUNCTOR>::times() const {
00155 return times_;
00156 }
00157
00158 }
00159
00160 #if defined(OPENGM_TIMER_WINDOWS)
00161 # undef WIN32_LEAN_AND_MEAN
00162 #endif
00163
00164 #endif // OPENGM_TIMER_HXX