Ignore:
Timestamp:
Mar 2, 2013, 10:45:46 PM (13 years ago)
Author:
Frederik Heber <heber@…>
Children:
b9273a
Parents:
8f60da
git-author:
Frederik Heber <heber@…> (03/01/13 13:41:05)
git-committer:
Frederik Heber <heber@…> (03/02/13 22:45:46)
Message:

Enhanced Chronos for more accurate timekeeping.

  • Chronos is now safe to use w.r.t. recursive function calls.
  • Chronos now gets const ref of token name in each function.
  • TESTFIX: dummyTest() now checks on recursive function.
  • Chronos now offers its internal timekeeping via const ref to outside.
  • Chronos also now has up to nanoseconds precision when either time.h or sys/time.h is present.
  • librt required from clock_gettime().
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Helpers/Chronos.cpp

    r8f60da r3f06bb  
    3939
    4040Chronos::Chronos()
    41 {}
     41{
     42  // get time and store it internally as base time
     43#ifdef HAVE_TIME_H
     44  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &basetime);
     45#else
     46#ifdef HAVE_SYS_TIME_H
     47  struct timezone timezone1;
     48  gettimeofday(&basetime, &timezone1);
     49#else
     50#ifdef HAVE_SYS_TIMES_H
     51  struct tms *basetime = new tms;
     52  times(basetime);
     53#endif
     54#endif
     55#endif
     56}
    4257
    4358Chronos::~Chronos()
    44 {}
    45 
    46 double Chronos::getTime(const std::string _name) const
     59{
     60#ifndef HAVE_TIME_H
     61#ifndef HAVE_SYS_TIME_H
     62#ifdef HAVE_SYS_TIMES_H
     63  delete basetime;
     64#endif
     65#endif
     66#endif
     67}
     68
     69double Chronos::getTime(const std::string &_name) const
    4770{
    4871  // only those functions have a time that have run already
    49   if (TimeRunning.count(_name)) {
     72  if (AccountedTime.count(_name) != 0) {
    5073    // return -1 if function is currently running
    51     if (TimeRunning.count(_name) != 0.)
     74    if (StartingTime.count(_name) == 0.)
    5275      return AccountedTime.at(_name);
    5376    else
     
    5780}
    5881
    59 void Chronos::resetTime(const std::string _name)
    60 {
    61   if (TimeRunning.count(_name)) {
     82void Chronos::resetTime(const std::string &_name)
     83{
     84  // set accounted time to zero
     85  if (AccountedTime.count(_name) != 0) {
    6286    AccountedTime[_name] = 0.;
    6387  }
    64 }
    65 
    66 void Chronos::startTiming(const std::string _name)
     88  // and end if it's currently running
     89  StartingTime.erase(_name);
     90  RecursionMap.erase(_name);
     91}
     92
     93void Chronos::startTiming(const std::string &_name)
    6794{
    6895  // start time keeping
    69   TimeRunning[_name] = getCurrentTime();
     96  if ((RecursionMap.count(_name) == 0) || (RecursionMap[_name] == 0)) {
     97    StartingTime[_name] = getCurrentTime();
     98    RecursionMap[_name] = 1;
     99  } else {
     100    ++RecursionMap[_name];
     101  }
    70102}
    71103
    72104double Chronos::getCurrentTime() const
    73105{
    74 #ifdef HAVE_SYS_TIMES_H
     106#ifdef HAVE_TIME_H
     107  // clock_gettime gives nanoseconds accuracy
     108  timespec time1;
     109  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
     110  double currenttime;
     111  if (time1.tv_nsec < basetime.tv_nsec)
     112    currenttime = (time1.tv_sec - basetime.tv_sec - 1)
     113        + (basetime.tv_nsec - time1.tv_nsec) * 1.e-9;
     114  else
     115    currenttime = (time1.tv_sec - basetime.tv_sec)
     116        + (time1.tv_nsec - basetime.tv_nsec) * 1.e-9;
     117#else
     118#ifdef HAVE_SYS_TIME_H
     119  struct timezone timezone1;
     120  timeval time1;
     121  // gettimeofday gives microseconds accuracy
     122  gettimeofday(&time1, &timezone1);
     123  double currenttime;
     124  if (time1.tv_usec < basetime.tv_usec)
     125    currenttime = (time1.tv_sec - basetime.tv_sec - 1)
     126        + (basetime.tv_usec - time1.tv_usec) * 1.e-6;
     127  else
     128    currenttime = (time1.tv_sec - basetime.tv_sec)
     129        + (time1.tv_usec - basetime.tv_usec) * 1.e-6;
     130#else
     131#ifdef HAVE_SYS_TIMES_H
     132  // clock is only accurate up to milliseconds
    75133  struct tms *buffer = new tms;
    76134  double currenttime;
    77135  if (times(buffer) != (clock_t)(-1))
    78     currenttime = ((double)buffer->tms_utime/(double)sysconf(_SC_CLK_TCK));
     136    currenttime =
     137        (double)(buffer->tms_utime - basetime->tms_utime)/(double)sysconf(_SC_CLK_TCK);
    79138  else
    80139    currenttime = 0.;
    81140  delete buffer;
    82141#else
    83   const double currenttime = (clock()/(double)CLOCKS_PER_SEC);
     142  // no time keeping possible
     143  const double currenttime = 0.;
     144#endif
     145#endif
    84146#endif
    85147  //std::cout << "Current time is " << currenttime << std::endl;
     
    87149}
    88150
    89 void Chronos::endTiming(const std::string _name)
    90 {
     151void Chronos::endTiming(const std::string &_name)
     152{
     153  // check whether we are the topmost function, return if not
     154  if (--RecursionMap[_name] != 0)
     155    return;
     156
     157  // if present
     158  ASSERT(StartingTime.count(_name), "Chronos::endTiming() - no timer under "
     159      +_name+" running.");
     160  ASSERT(RecursionMap.count(_name), "Chronos::endTiming() - negative recursion level for "
     161      +_name+".");
     162
     163  // finish time keeping
    91164  const double endtime = getCurrentTime();
    92   const double starttime = TimeRunning[_name];
    93 
    94   // if present
    95   ASSERT(TimeRunning.count(_name), "Chronos::endTiming() - no timer under "+_name+" running.");
    96   // finish time keeping
     165  const double starttime = StartingTime[_name];
    97166  const double RunTime = ((double)endtime - starttime);
    98   TimekeepingMap::iterator iter = AccountedTime.find(_name);
    99   if (iter != AccountedTime.end())
     167  if (AccountedTime.count(_name) != 0)
    100168    AccountedTime[_name] += RunTime;
    101169  else
     
    103171
    104172  // and zero for next run
    105   TimeRunning[_name] = 0.;
     173  StartingTime.erase(_name);
    106174}
    107175
     
    119187size_t Chronos::SumUpTotalFunctions() const
    120188{
    121   return TimeRunning.size();
     189  return AccountedTime.size();
    122190}
    123191
Note: See TracChangeset for help on using the changeset viewer.