X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FTimer.h;h=71b7ee58fd3caa9041c56e7af041abc4dfe1511e;hb=38b06447615440f935008a2141bd0a1fe078d437;hp=93d9d166093541737ab76e49dbf0009cbbd120fa;hpb=6c38a79d770f3f0eaa11694ad84ca729b75272c4;p=oota-llvm.git diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index 93d9d166093..71b7ee58fd3 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -1,80 +1,99 @@ -//===-- Support/Timer.h - Interval Timing Support ---------------*- C++ -*-===// +//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===// // -// This file defines three classes: Timer, TimeRegion, and TimerGroup. +// The LLVM Compiler Infrastructure // -// The Timer class is used to track the amount of time spent between invocations -// of it's startTimer()/stopTimer() methods. Given appropriate OS support it -// can also keep track of the RSS of the program at various points. By default, -// the Timer will print the amount of time it has captured to standard error -// when the laster timer is destroyed, otherwise it is printed when it's -// TimerGroup is destroyed. Timer's do not print their information if they are -// never started. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // -// The TimeRegion class is used as a helper class to call the startTimer() and -// stopTimer() methods of the Timer class. When the object is constructed, it -// starts the timer specified as it's argument. When it is destroyed, it stops -// the relevant timer. This makes it easy to time a region of code. +//===----------------------------------------------------------------------===// // -// The TimerGroup class is used to group together related timers into a single -// report that is printed when the TimerGroup is destroyed. It is illegal to -// destroy a TimerGroup object before all of the Timers in it are gone. A -// TimerGroup can be specified for a newly created timer in its constructor. +// This file defines three classes: Timer, TimeRegion, and TimerGroup, +// documented below. // //===----------------------------------------------------------------------===// -#ifndef SUPPORT_TIMER_H -#define SUPPORT_TIMER_H +#ifndef LLVM_SUPPORT_TIMER_H +#define LLVM_SUPPORT_TIMER_H +#include "llvm/Support/DataTypes.h" +#include "llvm/System/Mutex.h" #include #include +#include +#include + +namespace llvm { class TimerGroup; +/// Timer - This class is used to track the amount of time spent between +/// invocations of it's startTimer()/stopTimer() methods. Given appropriate OS +/// support it can also keep track of the RSS of the program at various points. +/// By default, the Timer will print the amount of time it has captured to +/// standard error when the laster timer is destroyed, otherwise it is printed +/// when its TimerGroup is destroyed. Timers do not print their information +/// if they are never started. +/// class Timer { double Elapsed; // Wall clock time elapsed in seconds double UserTime; // User time elapsed double SystemTime; // System time elapsed - unsigned long MaxRSS; // Maximum resident set size (in bytes) - unsigned long RSSTemp; // Temp for calculating maxrss + ssize_t MemUsed; // Memory allocated (in bytes) + size_t PeakMem; // Peak memory used + size_t PeakMemBase; // Temporary for peak calculation... std::string Name; // The name of this time variable bool Started; // Has this time variable ever been started? TimerGroup *TG; // The TimerGroup this Timer is in. + mutable sys::SmartMutex Lock; // Mutex for the contents of this Timer. public: - Timer(const std::string &N); + explicit Timer(const std::string &N); Timer(const std::string &N, TimerGroup &tg); Timer(const Timer &T); ~Timer(); double getProcessTime() const { return UserTime+SystemTime; } double getWallTime() const { return Elapsed; } - unsigned long getMaxRSS() const { return MaxRSS; } - std::string getName() const { return Name; } + ssize_t getMemUsed() const { return MemUsed; } + size_t getPeakMem() const { return PeakMem; } + std::string getName() const { return Name; } const Timer &operator=(const Timer &T) { + if (&T < this) { + T.Lock.acquire(); + Lock.acquire(); + } else { + Lock.acquire(); + T.Lock.acquire(); + } + Elapsed = T.Elapsed; UserTime = T.UserTime; SystemTime = T.SystemTime; - MaxRSS = T.MaxRSS; - RSSTemp = T.RSSTemp; + MemUsed = T.MemUsed; + PeakMem = T.PeakMem; + PeakMemBase = T.PeakMemBase; Name = T.Name; Started = T.Started; - assert (TG == T.TG && "Can only assign timers in the same TimerGroup!"); + assert(TG == T.TG && "Can only assign timers in the same TimerGroup!"); + + if (&T < this) { + T.Lock.release(); + Lock.release(); + } else { + Lock.release(); + T.Lock.release(); + } + return *this; } // operator< - Allow sorting... bool operator<(const Timer &T) const { - // Primary sort key is User+System time - if (UserTime+SystemTime < T.UserTime+T.SystemTime) - return true; - if (UserTime+SystemTime > T.UserTime+T.SystemTime) - return false; - - // Secondary sort key is Wall Time + // Sort by Wall Time elapsed, as it is the only thing really accurate return Elapsed < T.Elapsed; } bool operator>(const Timer &T) const { return T.operator<(*this); } - + /// startTimer - Start the timer running. Time between calls to /// startTimer/stopTimer is counted by the Timer class. Note that these calls /// must be correctly paired. @@ -85,9 +104,15 @@ public: /// void stopTimer(); + /// addPeakMemoryMeasurement - This method should be called whenever memory + /// usage needs to be checked. It adds a peak memory measurement to the + /// currently active timers, which will be printed when the timer group prints + /// + static void addPeakMemoryMeasurement(); + /// print - Print the current timer to standard error, and reset the "Started" /// flag. - void print(const Timer &Total); + void print(const Timer &Total, std::ostream &OS); private: friend class TimerGroup; @@ -101,24 +126,52 @@ private: }; +/// The TimeRegion class is used as a helper class to call the startTimer() and +/// stopTimer() methods of the Timer class. When the object is constructed, it +/// starts the timer specified as it's argument. When it is destroyed, it stops +/// the relevant timer. This makes it easy to time a region of code. +/// class TimeRegion { - Timer &T; + Timer *T; TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT public: - TimeRegion(Timer &t) : T(t) { - T.startTimer(); + explicit TimeRegion(Timer &t) : T(&t) { + T->startTimer(); + } + explicit TimeRegion(Timer *t) : T(t) { + if (T) + T->startTimer(); } ~TimeRegion() { - T.stopTimer(); + if (T) + T->stopTimer(); } }; + +/// NamedRegionTimer - This class is basically a combination of TimeRegion and +/// Timer. It allows you to declare a new timer, AND specify the region to +/// time, all in one statement. All timers with the same name are merged. This +/// is primarily used for debugging and for hunting performance problems. +/// +struct NamedRegionTimer : public TimeRegion { + explicit NamedRegionTimer(const std::string &Name); + explicit NamedRegionTimer(const std::string &Name, + const std::string &GroupName); +}; + + +/// The TimerGroup class is used to group together related timers into a single +/// report that is printed when the TimerGroup is destroyed. It is illegal to +/// destroy a TimerGroup object before all of the Timers in it are gone. A +/// TimerGroup can be specified for a newly created timer in its constructor. +/// class TimerGroup { std::string Name; unsigned NumTimers; std::vector TimersToPrint; public: - TimerGroup(const std::string &name) : Name(name), NumTimers(0) {} + explicit TimerGroup(const std::string &name) : Name(name), NumTimers(0) {} ~TimerGroup() { assert(NumTimers == 0 && "TimerGroup destroyed before all contained timers!"); @@ -126,11 +179,11 @@ public: private: friend class Timer; - void addTimer() { ++NumTimers; } + void addTimer(); void removeTimer(); - void addTimerToPrint(const Timer &T) { - TimersToPrint.push_back(Timer(true, T)); - } + void addTimerToPrint(const Timer &T); }; +} // End llvm namespace + #endif