CVD 0.8
cvd/timer.h
00001 /*
00002     This file is part of the CVD Library.
00003 
00004     Copyright (C) 2005 The Authors
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2.1 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public
00017     License along with this library; if not, write to the Free Software
00018     Foundation, Inc.,
00019     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 */
00022 //
00023 // A timer class designed for dealing with timestamps
00024 // CK Nov 2002
00025 //
00027 
00028 #ifndef __CVD_TIMER_H
00029 #define __CVD_TIMER_H
00030 #include <iostream>
00031 #include <string>
00032 #include <cassert>
00033 #include <deque>
00034 struct timeval;
00035 
00036 namespace CVD {
00037 
00044 class cvd_timer
00045 {
00046     public:
00048         cvd_timer();
00049 
00051         cvd_timer(double start);
00052 
00054         double get_time();
00055 
00059         double conv_ntime(signed long long time);
00060 
00064         double conv_ntime(const struct timeval& tv);
00065 
00068         double conv_ntime(const double & time) const {
00069             return time - startTimeInNanoSeconds * 1.e-9;
00070         }
00071 
00073         double reset();
00074         
00077         void reset(const double t);
00078         
00081         void reset_ns(long long t);
00082 
00083     private:
00084         long long startTimeInNanoSeconds;
00085 };
00086 
00087 extern cvd_timer timer;
00088 
00091 double get_time_of_day();
00092 
00093 
00096 long long get_time_of_day_ns();
00097 
00098 
00103 class SimpleTimer
00104 {
00105     public:
00111         SimpleTimer(const std::string &description, const int &cycles_to_time=1, bool output=true, std::ostream &out=std::cout) : output_info(output), max(0), min(0), average(0), text(description), period(cycles_to_time), increment(0), timings(0), cumulative_time(0), time_at_start_of_timing(0), timing_started(false), sout(out)
00112         {
00113             assert(period>0);
00114             internal_cvd_timer=new cvd_timer();
00115         }
00116 
00118         ~SimpleTimer()
00119         {
00120             delete internal_cvd_timer;
00121         }
00122 
00124         void click()
00125         {
00126                 if (!timing_started)
00127                 {
00128                     timing_started=true;
00129                     time_at_start_of_timing=internal_cvd_timer->get_time();
00130                 }
00131                 else if (timing_started)
00132                 {
00133                     increment=internal_cvd_timer->get_time()-time_at_start_of_timing;
00134                     time_buffer.push_back(increment);
00135                     if((int)time_buffer.size()>period&&period>0)
00136                         time_buffer.pop_front();
00137                     timings++;
00138                     timing_started=false;
00139                     if (timings%period==0 && output_info)
00140                         print();
00141                 }
00142         }
00143 
00146         void print()
00147         {
00148             if(timings>0)
00149             {
00150                 if((int)time_buffer.size()==1)
00151                     sout<<text<<" takes: "<<get_average()<<"s over 1 timing"<<std::endl;
00152                 else
00153                     sout<<text<<" takes : av "<<get_average()<<"s , max "<<get_max()<<"s, min "<<get_min()<<"s, over "<<time_buffer.size()<<" timings"<<std::endl;
00154             }
00155             else
00156                 sout<<text<<" section : error. No timed cycles. Use click() to start and stop timing."<<std::endl;
00157         }
00158 
00160         double get_max(){
00161             max=-1;
00162             if (time_buffer.size()>0)
00163                 max=time_buffer[0];
00164             if(time_buffer.size()>1)
00165                 for(int i=0; i<(int)time_buffer.size(); ++i)
00166                     max=std::max(time_buffer[i], max);
00167 
00168             return max;
00169 
00170         }
00171 
00173         double get_min(){
00174             min=-1;
00175             if (time_buffer.size()>0)
00176                 min=time_buffer[0];
00177             if(time_buffer.size()>1)
00178                 for(int i=0; i<(int)time_buffer.size(); ++i)
00179                     min=std::min(time_buffer[i], min);
00180             return min;
00181         }
00182 
00184         double get_average(){
00185             average=-1;
00186             if(time_buffer.size()>0){
00187             cumulative_time=0;
00188             for(int i=0; i<(int)time_buffer.size(); ++i)
00189                 cumulative_time+=time_buffer[i];
00190             average=cumulative_time/time_buffer.size();
00191             }
00192             return average;
00193         }
00194 
00195     private:
00196         bool output_info;
00197         double max, min, average;
00198         std::string text;
00199         int period;
00200         double increment;
00201         int timings;
00202         double cumulative_time;
00203         double time_at_start_of_timing;
00204         bool timing_started;
00205         cvd_timer* internal_cvd_timer;
00206         std::ostream& sout;
00207         std::deque<double> time_buffer;
00208 
00209 
00210 };
00211 
00212 }
00213 
00214 #endif