00001
00023 #ifndef GALOIS_STATISTIC_H
00024 #define GALOIS_STATISTIC_H
00025
00026 #include "Galois/config.h"
00027 #include "Galois/Runtime/Support.h"
00028 #include "Galois/Runtime/PerThreadStorage.h"
00029 #include "Galois/Runtime/Sampling.h"
00030 #include "Galois/Timer.h"
00031
00032 #include "boost/utility.hpp"
00033
00034 #include GALOIS_CXX11_STD_HEADER(deque)
00035
00036 namespace Galois {
00037
00041 class Statistic {
00042 std::string statname;
00043 std::string loopname;
00044 Galois::Runtime::PerThreadStorage<unsigned long> val;
00045 bool valid;
00046
00047 public:
00048 Statistic(const std::string& _sn, std::string _ln = "(NULL)"): statname(_sn), loopname(_ln), valid(true) { }
00049
00050 ~Statistic() {
00051 report();
00052 }
00053
00055 void report() {
00056 if (valid)
00057 Galois::Runtime::reportStat(this);
00058 valid = false;
00059 }
00060
00061 unsigned long getValue(unsigned tid) {
00062 return *val.getRemote(tid);
00063 }
00064
00065 std::string& getLoopname() {
00066 return loopname;
00067 }
00068
00069 std::string& getStatname() {
00070 return statname;
00071 }
00072
00073 Statistic& operator+=(unsigned long v) {
00074 *val.getLocal() += v;
00075 return *this;
00076 }
00077 };
00078
00083 class StatManager: private boost::noncopyable {
00084 std::deque<Statistic*> stats;
00085
00086 public:
00087 ~StatManager() {
00088 for (std::deque<Statistic*>::iterator ii = stats.begin(), ei = stats.end(); ii != ei; ++ii) {
00089 (*ii)->report();
00090 }
00091 Galois::Runtime::printStats();
00092 }
00093
00095 void push(Statistic& s) {
00096 stats.push_back(&s);
00097 }
00098 };
00099
00101 struct start_now_t {};
00102 #if defined(__IBMCPP__) && __IBMCPP__ <= 1210
00103 static const start_now_t start_now = start_now_t();
00104 #else
00105 constexpr start_now_t start_now = start_now_t();
00106 #endif
00107
00109 class StatTimer : public TimeAccumulator {
00110 const char* name;
00111 const char* loopname;
00112 bool main;
00113 bool valid;
00114
00115 protected:
00116 void init(const char* n, const char* l, bool m, bool s) {
00117 name = n;
00118 loopname = l;
00119 main = m;
00120 valid = false;
00121 if (s)
00122 start();
00123 }
00124
00125 public:
00126 StatTimer(const char* n) { init(n, 0, false, false); }
00127 StatTimer(const char* n, start_now_t t) { init(n, 0, false, true); }
00128
00129 StatTimer(const char* n, const char* l) { init(n, l, false, false); }
00130 StatTimer(const char* n, const char* l, start_now_t t) { init(n, l, false, true); }
00131
00132 StatTimer() { init("Time", 0, true, false); }
00133 StatTimer(start_now_t t) { init("Time", 0, true, true); }
00134
00135 ~StatTimer() {
00136 if (valid)
00137 stop();
00138 if (TimeAccumulator::get())
00139 Galois::Runtime::reportStat(loopname, name, get());
00140 }
00141
00142 void start() {
00143 if (main)
00144 Galois::Runtime::beginSampling();
00145 TimeAccumulator::start();
00146 valid = true;
00147 }
00148
00149 void stop() {
00150 valid = false;
00151 TimeAccumulator::stop();
00152 if (main)
00153 Galois::Runtime::endSampling();
00154 }
00155 };
00156
00157 }
00158 #endif