X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=support%2Flib%2FSupport%2FTimer.cpp;h=62876539ff2664d3c67e57e7abf1ee1907f8b144;hb=8166b7cdb891e0d3c5789260248211a8b6e99787;hp=a214cf419acd02dccbf1b378ef3f43b65d815040;hpb=18eba91a05ccff184820f8afddfddada15e35e65;p=oota-llvm.git diff --git a/support/lib/Support/Timer.cpp b/support/lib/Support/Timer.cpp index a214cf419ac..62876539ff2 100644 --- a/support/lib/Support/Timer.cpp +++ b/support/lib/Support/Timer.cpp @@ -5,6 +5,7 @@ //===----------------------------------------------------------------------===// #include "Support/Timer.h" +#include "Support/CommandLine.h" #include #include #include @@ -15,6 +16,13 @@ #include #include +namespace { + cl::opt + TrackSpace("track-memory", cl::desc("Enable -time-passes memory " + "tracking (this may be slow)"), + cl::Hidden); +} + static TimerGroup *DefaultTimerGroup = 0; static TimerGroup *getDefaultTimerGroup() { if (DefaultTimerGroup) return DefaultTimerGroup; @@ -22,13 +30,13 @@ static TimerGroup *getDefaultTimerGroup() { } Timer::Timer(const std::string &N) - : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), Name(N), + : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), PeakMem(0), Name(N), Started(false), TG(getDefaultTimerGroup()) { TG->addTimer(); } Timer::Timer(const std::string &N, TimerGroup &tg) - : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), Name(N), + : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), PeakMem(0), Name(N), Started(false), TG(&tg) { TG->addTimer(); } @@ -58,49 +66,74 @@ Timer::~Timer() { } } +static long getMemUsage() { + if (TrackSpace) { + struct mallinfo MI = mallinfo(); + return MI.uordblks/*+MI.hblkhd*/; + } else { + return 0; + } +} + struct TimeRecord { double Elapsed, UserTime, SystemTime; long MemUsed; }; -static TimeRecord getTimeRecord() { +static TimeRecord getTimeRecord(bool Start) { struct rusage RU; struct timeval T; + long MemUsed = 0; + if (Start) { + MemUsed = getMemUsage(); + if (getrusage(RUSAGE_SELF, &RU)) + perror("getrusage call failed: -time-passes info incorrect!"); + } gettimeofday(&T, 0); - if (getrusage(RUSAGE_SELF, &RU)) { - perror("getrusage call failed: -time-passes info incorrect!"); + + if (!Start) { + MemUsed = getMemUsage(); + if (getrusage(RUSAGE_SELF, &RU)) + perror("getrusage call failed: -time-passes info incorrect!"); } TimeRecord Result; Result.Elapsed = T.tv_sec + T.tv_usec/1000000.0; Result.UserTime = RU.ru_utime.tv_sec + RU.ru_utime.tv_usec/1000000.0; Result.SystemTime = RU.ru_stime.tv_sec + RU.ru_stime.tv_usec/1000000.0; - -#ifndef __sparc__ - struct mallinfo MI = mallinfo(); - Result.MemUsed = MI.uordblks; -#else - Result.MemUsed = 0; -#endif + Result.MemUsed = MemUsed; return Result; } +static std::vector ActiveTimers; + void Timer::startTimer() { Started = true; - TimeRecord TR = getTimeRecord(); + TimeRecord TR = getTimeRecord(true); Elapsed -= TR.Elapsed; UserTime -= TR.UserTime; SystemTime -= TR.SystemTime; MemUsed -= TR.MemUsed; + PeakMemBase = TR.MemUsed; + ActiveTimers.push_back(this); } void Timer::stopTimer() { - TimeRecord TR = getTimeRecord(); + TimeRecord TR = getTimeRecord(false); Elapsed += TR.Elapsed; UserTime += TR.UserTime; SystemTime += TR.SystemTime; MemUsed += TR.MemUsed; + + if (ActiveTimers.back() == this) { + ActiveTimers.pop_back(); + } else { + std::vector::iterator I = + std::find(ActiveTimers.begin(), ActiveTimers.end(), this); + assert(I != ActiveTimers.end() && "stop but no startTimer?"); + ActiveTimers.erase(I); + } } void Timer::sum(const Timer &T) { @@ -108,8 +141,22 @@ void Timer::sum(const Timer &T) { UserTime += T.UserTime; SystemTime += T.SystemTime; MemUsed += T.MemUsed; + PeakMem += T.PeakMem; +} + +/// 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 +/// +void Timer::addPeakMemoryMeasurement() { + long MemUsed = getMemUsage(); + + for (std::vector::iterator I = ActiveTimers.begin(), + E = ActiveTimers.end(); I != E; ++I) + (*I)->PeakMem = std::max((*I)->PeakMem, MemUsed-(*I)->PeakMemBase); } + //===----------------------------------------------------------------------===// // TimerGroup Implementation //===----------------------------------------------------------------------===// @@ -134,6 +181,12 @@ void Timer::print(const Timer &Total) { if (Total.MemUsed) fprintf(stderr, " %8ld ", MemUsed); + if (Total.PeakMem) { + if (PeakMem) + fprintf(stderr, " %8ld ", PeakMem); + else + fprintf(stderr, " "); + } std::cerr << Name << "\n"; Started = false; // Once printed, don't print again @@ -162,9 +215,11 @@ void TimerGroup::removeTimer() { std::cerr << "===" << std::string(73, '-') << "===\n" << std::string(Padding, ' ') << Name << "\n" << "===" << std::string(73, '-') - << "===\n Total Execution Time: " << Total.getProcessTime() - << " seconds (" << Total.getWallTime() - << " wall clock)\n\n"; + << "===\n Total Execution Time: "; + + // Hack for GCC 2.96... :( it doesn't support manipulators! + fprintf(stderr, "%.4f seconds (%.4f wall clock)\n\n", + Total.getProcessTime(), Total.getWallTime()); if (Total.UserTime) std::cerr << " ---User Time---"; @@ -175,6 +230,8 @@ void TimerGroup::removeTimer() { std::cerr << " ---Wall Time---"; if (Total.getMemUsed()) std::cerr << " ---Mem---"; + if (Total.getPeakMem()) + std::cerr << " -PeakMem-"; std::cerr << " --- Name ---\n"; // Loop through all of the timing data, printing it out...