Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:55

0001 /// \file Stopwatch.h
0002 /// \author Sandro Wenzel (sandro.wenzel@cern.ch)
0003 
0004 #ifndef VECGEOM_BASE_STOPWATCH_H_
0005 #define VECGEOM_BASE_STOPWATCH_H_
0006 
0007 #include "VecGeom/base/Global.h"
0008 
0009 // OS X compatibility
0010 #ifdef __MACH__
0011 #include <mach/clock.h>
0012 #include <mach/mach.h>
0013 #endif
0014 
0015 #include <ctime>
0016 #include <unistd.h>
0017 #include <sys/times.h>
0018 
0019 namespace vecgeom {
0020 inline namespace VECGEOM_IMPL_NAMESPACE {
0021 namespace standardtimer {
0022 // this implementation is stripped from the TBB library ( so that we don't need to link against tbb )
0023 
0024 typedef long long count_t;
0025 
0026 inline long long now()
0027 {
0028   count_t result;
0029   struct timespec ts;
0030 
0031 #ifdef __MACH__
0032   // OS X compatibility code taken from
0033   // http://stackoverflow.com/questions/5167269/
0034   clock_serv_t cclock;
0035   mach_timespec_t mts;
0036   host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
0037   clock_get_time(cclock, &mts);
0038   mach_port_deallocate(mach_task_self(), cclock);
0039   ts.tv_sec  = mts.tv_sec;
0040   ts.tv_nsec = mts.tv_nsec;
0041 #else
0042   clock_gettime(CLOCK_REALTIME, &ts);
0043 #endif
0044 
0045   result = static_cast<count_t>(1000000000UL) * static_cast<count_t>(ts.tv_sec) + static_cast<count_t>(ts.tv_nsec);
0046   return result;
0047 }
0048 
0049 inline double seconds(count_t value)
0050 {
0051   return value * 1E-9;
0052 }
0053 }
0054 
0055 /**
0056  * @brief Timer for benchmarking purposes
0057  */
0058 class Stopwatch {
0059   // Note see http://jogojapan.github.io/blog/2012/11/25/measuring-cpu-time/
0060   // for some interesting ideas on how to implement in a
0061 private:
0062   standardtimer::count_t t1;
0063   standardtimer::count_t t2;
0064   double fCpuStart;
0065   double fCpuStop;
0066 
0067   static std::intmax_t GetTickFactor()
0068   {
0069     auto setter = []() {
0070       std::intmax_t result = ::sysconf(_SC_CLK_TCK);
0071       if (result <= 0) {
0072         fprintf(stderr,
0073                 "Error StopWatch::GetTickFactor: Could not retrieve number of clock ticks per second (_SC_CLK_TCK).\n");
0074         result = -1;
0075       }
0076       return result;
0077     };
0078     static std::intmax_t result = setter();
0079     return result;
0080   }
0081 
0082   double GetCPUTime()
0083   {
0084     struct tms cpt;
0085     times(&cpt);
0086     return (double)(cpt.tms_utime + cpt.tms_stime) / GetTickFactor();
0087   }
0088 
0089 public:
0090   inline void Start()
0091   {
0092     t1        = standardtimer::now();
0093     fCpuStart = GetCPUTime();
0094   }
0095 
0096   /**
0097    * @return Elapsed time since start.
0098    */
0099   inline double Stop()
0100   {
0101     t2       = standardtimer::now();
0102     fCpuStop = GetCPUTime();
0103     return Elapsed();
0104   }
0105 
0106   inline double Elapsed() const { return standardtimer::seconds(t2 - t1); }
0107 
0108   inline double CpuElapsed() const { return fCpuStop - fCpuStart; }
0109 };
0110 }
0111 } // End global namespace
0112 
0113 #endif // VECGEOM_BASE_STOPWATCH_H_