LLVM API Documentation
00001 //===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines three classes: Timer, TimeRegion, and TimerGroup, 00011 // documented below. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_SUPPORT_TIMER_H 00016 #define LLVM_SUPPORT_TIMER_H 00017 00018 #include <string> 00019 #include <vector> 00020 #include <iosfwd> 00021 #include <cassert> 00022 00023 namespace llvm { 00024 00025 class TimerGroup; 00026 00027 /// Timer - This class is used to track the amount of time spent between 00028 /// invocations of it's startTimer()/stopTimer() methods. Given appropriate OS 00029 /// support it can also keep track of the RSS of the program at various points. 00030 /// By default, the Timer will print the amount of time it has captured to 00031 /// standard error when the laster timer is destroyed, otherwise it is printed 00032 /// when it's TimerGroup is destroyed. Timer's do not print their information 00033 /// if they are never started. 00034 /// 00035 class Timer { 00036 double Elapsed; // Wall clock time elapsed in seconds 00037 double UserTime; // User time elapsed 00038 double SystemTime; // System time elapsed 00039 long MemUsed; // Memory allocated (in bytes) 00040 long PeakMem; // Peak memory used 00041 long PeakMemBase; // Temporary for peak calculation... 00042 std::string Name; // The name of this time variable 00043 bool Started; // Has this time variable ever been started? 00044 TimerGroup *TG; // The TimerGroup this Timer is in. 00045 public: 00046 Timer(const std::string &N); 00047 Timer(const std::string &N, TimerGroup &tg); 00048 Timer(const Timer &T); 00049 ~Timer(); 00050 00051 double getProcessTime() const { return UserTime+SystemTime; } 00052 double getWallTime() const { return Elapsed; } 00053 long getMemUsed() const { return MemUsed; } 00054 long getPeakMem() const { return PeakMem; } 00055 std::string getName() const { return Name; } 00056 00057 const Timer &operator=(const Timer &T) { 00058 Elapsed = T.Elapsed; 00059 UserTime = T.UserTime; 00060 SystemTime = T.SystemTime; 00061 MemUsed = T.MemUsed; 00062 PeakMem = T.PeakMem; 00063 PeakMemBase = T.PeakMemBase; 00064 Name = T.Name; 00065 Started = T.Started; 00066 assert(TG == T.TG && "Can only assign timers in the same TimerGroup!"); 00067 return *this; 00068 } 00069 00070 // operator< - Allow sorting... 00071 bool operator<(const Timer &T) const { 00072 // Sort by Wall Time elapsed, as it is the only thing really accurate 00073 return Elapsed < T.Elapsed; 00074 } 00075 bool operator>(const Timer &T) const { return T.operator<(*this); } 00076 00077 /// startTimer - Start the timer running. Time between calls to 00078 /// startTimer/stopTimer is counted by the Timer class. Note that these calls 00079 /// must be correctly paired. 00080 /// 00081 void startTimer(); 00082 00083 /// stopTimer - Stop the timer. 00084 /// 00085 void stopTimer(); 00086 00087 /// addPeakMemoryMeasurement - This method should be called whenever memory 00088 /// usage needs to be checked. It adds a peak memory measurement to the 00089 /// currently active timers, which will be printed when the timer group prints 00090 /// 00091 static void addPeakMemoryMeasurement(); 00092 00093 /// print - Print the current timer to standard error, and reset the "Started" 00094 /// flag. 00095 void print(const Timer &Total, std::ostream &OS); 00096 00097 private: 00098 friend class TimerGroup; 00099 00100 // Copy ctor, initialize with no TG member. 00101 Timer(bool, const Timer &T); 00102 00103 /// sum - Add the time accumulated in the specified timer into this timer. 00104 /// 00105 void sum(const Timer &T); 00106 }; 00107 00108 00109 /// The TimeRegion class is used as a helper class to call the startTimer() and 00110 /// stopTimer() methods of the Timer class. When the object is constructed, it 00111 /// starts the timer specified as it's argument. When it is destroyed, it stops 00112 /// the relevant timer. This makes it easy to time a region of code. 00113 /// 00114 class TimeRegion { 00115 Timer &T; 00116 TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT 00117 public: 00118 TimeRegion(Timer &t) : T(t) { 00119 T.startTimer(); 00120 } 00121 ~TimeRegion() { 00122 T.stopTimer(); 00123 } 00124 }; 00125 00126 00127 /// NamedRegionTimer - This class is basically a combination of TimeRegion and 00128 /// Timer. It allows you to declare a new timer, AND specify the region to 00129 /// time, all in one statement. All timers with the same name are merged. This 00130 /// is primarily used for debugging and for hunting performance problems. 00131 /// 00132 struct NamedRegionTimer : public TimeRegion { 00133 NamedRegionTimer(const std::string &Name); 00134 }; 00135 00136 00137 /// The TimerGroup class is used to group together related timers into a single 00138 /// report that is printed when the TimerGroup is destroyed. It is illegal to 00139 /// destroy a TimerGroup object before all of the Timers in it are gone. A 00140 /// TimerGroup can be specified for a newly created timer in its constructor. 00141 /// 00142 class TimerGroup { 00143 std::string Name; 00144 unsigned NumTimers; 00145 std::vector<Timer> TimersToPrint; 00146 public: 00147 TimerGroup(const std::string &name) : Name(name), NumTimers(0) {} 00148 ~TimerGroup() { 00149 assert(NumTimers == 0 && 00150 "TimerGroup destroyed before all contained timers!"); 00151 } 00152 00153 private: 00154 friend class Timer; 00155 void addTimer() { ++NumTimers; } 00156 void removeTimer(); 00157 void addTimerToPrint(const Timer &T) { 00158 TimersToPrint.push_back(Timer(true, T)); 00159 } 00160 }; 00161 00162 } // End llvm namespace 00163 00164 #endif