Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:47

0001 //
0002 // MIT License
0003 // Copyright (c) 2019 Jonathan R. Madsen
0004 // Permission is hereby granted, free of charge, to any person obtaining a copy
0005 // of this software and associated documentation files (the "Software"), to deal
0006 // in the Software without restriction, including without limitation the rights
0007 // to use, copy, modify, merge, publish, distribute, sublicense, and
0008 // copies of the Software, and to permit persons to whom the Software is
0009 // furnished to do so, subject to the following conditions:
0010 // The above copyright notice and this permission notice shall be included in
0011 // all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
0012 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
0013 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
0014 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
0015 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0016 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
0017 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0018 //
0019 // ----------------------------------------------------------------------
0020 // Class Timer
0021 //
0022 // Class description:
0023 //
0024 // Class for timer objects, able to measure elasped user/system process time.
0025 //
0026 // Note: Uses <sys/times.h> & <unistd.h> - POSIX.1 defined
0027 //       If used, this header must be included in the source (.cc) file and it
0028 //       must be the first header file to be included!
0029 //
0030 // Member functions:
0031 //
0032 // Timer()
0033 //   Construct a timer object
0034 // Start()
0035 //   Start timing
0036 // Stop()
0037 //   Stop timing
0038 // bool IsValid()
0039 //   Return true if have a valid time (ie start() and stop() called)
0040 // double GetRealElapsed()
0041 //   Return the elapsed real time between last calling start() and stop()
0042 // double GetSystemElapsed()
0043 //   Return the elapsed system time between last calling start() and stop()
0044 // double GetUserElapsed()
0045 //   Return the elapsed user time between last calling start() and stop()
0046 //
0047 // Operators:
0048 //
0049 // std::ostream& operator << (std::ostream& os, const Timer& t);
0050 //   Print the elapsed real,system and usertimes on os. Prints **s for times
0051 //   if !IsValid
0052 //
0053 // Member data:
0054 //
0055 // bool fValidTimes
0056 //   True after start and stop have both been called more than once and
0057 //   an equal number of times
0058 // clock_t fStartRealTime,fEndRealTime
0059 //   Real times (arbitrary time 0)
0060 // tms fStartTimes,fEndTimes
0061 //   Timing structures (see times(2)) for start and end times
0062 
0063 // History:
0064 // 23.08.96 P.Kent Updated to also computed real elapsed time
0065 // 21.08.95 P.Kent
0066 // 29.04.97 G.Cosmo Added timings for Windows/NT
0067 
0068 #pragma once
0069 
0070 #include "PTL/Types.hh"
0071 
0072 #include <chrono>
0073 #include <iomanip>
0074 #include <sstream>
0075 
0076 #if !(defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64))
0077 #    include <sys/times.h>
0078 #    include <time.h>
0079 #else
0080 #    include <ctime>
0081 #    define _SC_CLK_TCK 1
0082 
0083 extern "C"
0084 {
0085     int sysconf(int);
0086 };
0087 
0088 // Structure returned by times()
0089 
0090 struct tms
0091 {
0092     clock_t tms_utime;  /* user time */
0093     clock_t tms_stime;  /* system time */
0094     clock_t tms_cutime; /* user time, children */
0095     clock_t tms_cstime; /* system time, children */
0096 };
0097 
0098 extern "C"
0099 {
0100     extern clock_t times(struct tms*);
0101 };
0102 #endif /* WIN32 */
0103 
0104 namespace PTL
0105 {
0106 class Timer
0107 {
0108 public:
0109     PTL_DEFAULT_OBJECT(Timer)
0110 
0111 public:
0112     void   Start();
0113     void   Stop();
0114     bool   IsValid() const;
0115     double GetRealElapsed() const;
0116     double GetSystemElapsed() const;
0117     double GetUserElapsed() const;
0118 
0119     static const char* GetClockTime();
0120 
0121 private:
0122     bool fValidTimes{ false };
0123     using clock_type = std::chrono::high_resolution_clock;
0124     std::chrono::time_point<clock_type> fStartRealTime, fEndRealTime;
0125     tms                                 fStartTimes, fEndTimes;
0126 };
0127 
0128 // ------------------------------------------------------------
0129 //      class inline implementation
0130 // ------------------------------------------------------------
0131 
0132 inline void
0133 Timer::Start()
0134 {
0135     fValidTimes = false;
0136     times(&fStartTimes);
0137     fStartRealTime = clock_type::now();
0138 }
0139 
0140 inline void
0141 Timer::Stop()
0142 {
0143     times(&fEndTimes);
0144     fEndRealTime = clock_type::now();
0145     fValidTimes  = true;
0146 }
0147 
0148 inline bool
0149 Timer::IsValid() const
0150 {
0151     return fValidTimes;
0152 }
0153 
0154 inline const char*
0155 Timer::GetClockTime()
0156 {
0157     time_t     rawtime;
0158     struct tm* timeinfo;
0159 
0160     time(&rawtime);
0161     timeinfo = localtime(&rawtime);
0162     return asctime(timeinfo);
0163 }
0164 
0165 inline std::ostream&
0166 operator<<(std::ostream& os, const Timer& t)
0167 {
0168     // so fixed doesn't propagate
0169     std::stringstream ss;
0170     ss << std::fixed;
0171     if(t.IsValid())
0172     {
0173         ss << "Real=" << t.GetRealElapsed() << "s User=" << t.GetUserElapsed()
0174            << "s Sys=" << t.GetSystemElapsed() << "s";
0175 
0176         // avoid possible FPE error
0177         if(t.GetRealElapsed() > 1.0e-6)
0178         {
0179             double cpu_util =
0180                 (t.GetUserElapsed() + t.GetSystemElapsed()) / t.GetRealElapsed() * 100.0;
0181             ss << std::setprecision(1);
0182             ss << " [Cpu=" << std::setprecision(1) << cpu_util << "%]";
0183         }
0184     }
0185     else
0186     {
0187         ss << "Real=****s User=****s Sys=****s";
0188     }
0189     os << ss.str();
0190 
0191     return os;
0192 }
0193 
0194 }  // namespace PTL