X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fprofiler.h;h=6da11597262b384d54483a31918e744db7264117;hb=d176dabeb4f04f9a1179cad9b23653fe6e19169e;hp=a30e34a7c77dd06558d7efa40bf755d61f0b043f;hpb=223b3793485a76f87599d39364b1003c2ca7c49c;p=minetest.git diff --git a/src/profiler.h b/src/profiler.h index a30e34a7c..6da115972 100644 --- a/src/profiler.h +++ b/src/profiler.h @@ -1,18 +1,18 @@ /* -Minetest-c55 -Copyright (C) 2011 celeron55, Perttu Ahola +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ @@ -20,11 +20,21 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef PROFILER_HEADER #define PROFILER_HEADER -#include "common_irrlicht.h" +#include "irrlichttypes.h" #include -#include "utility.h" -#include -#include +#include + +#include "threading/mutex.h" +#include "threading/mutex_auto_lock.h" +#include "util/timetaker.h" +#include "util/numeric.h" // paging() +#include "debug.h" // assert() + +#define MAX_PROFILER_TEXT_ROWS 20 + +// Global profiler +class Profiler; +extern Profiler *g_profiler; /* Time profiler @@ -35,78 +45,170 @@ class Profiler public: Profiler() { - m_mutex.Init(); } - void add(const std::string &name, u32 duration) + void add(const std::string &name, float value) { - JMutexAutoLock lock(m_mutex); - core::map::Node *n = m_data.find(name); - if(n == NULL) + MutexAutoLock lock(m_mutex); { - m_data[name] = duration; + /* No average shall have been used; mark add used as -2 */ + std::map::iterator n = m_avgcounts.find(name); + if(n == m_avgcounts.end()) + m_avgcounts[name] = -2; + else{ + if(n->second == -1) + n->second = -2; + assert(n->second == -2); + } } - else { - n->setValue(n->getValue()+duration); + std::map::iterator n = m_data.find(name); + if(n == m_data.end()) + m_data[name] = value; + else + n->second += value; } } + void avg(const std::string &name, float value) + { + MutexAutoLock lock(m_mutex); + int &count = m_avgcounts[name]; + + assert(count != -2); + count = MYMAX(count, 0) + 1; + m_data[name] += value; + } + void clear() { - JMutexAutoLock lock(m_mutex); - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd() == false; i++) + MutexAutoLock lock(m_mutex); + for(std::map::iterator + i = m_data.begin(); + i != m_data.end(); ++i) { - i.getNode()->setValue(0); + i->second = 0; } + m_avgcounts.clear(); } void print(std::ostream &o) { - JMutexAutoLock lock(m_mutex); - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd() == false; i++) - { - std::string name = i.getNode()->getKey(); - o<::const_iterator numerator = m_data.find(name); + if (numerator == m_data.end()) + return 0.f; + + std::map::const_iterator denominator = m_avgcounts.find(name); + if (denominator != m_avgcounts.end()){ + if (denominator->second >= 1) + return numerator->second / denominator->second; + } + + return numerator->second; + } + + void printPage(std::ostream &o, u32 page, u32 pagecount) + { + MutexAutoLock lock(m_mutex); + + u32 minindex, maxindex; + paging(m_data.size(), page, pagecount, minindex, maxindex); + + for (std::map::const_iterator i = m_data.begin(); + i != m_data.end(); ++i) { + if (maxindex == 0) + break; + maxindex--; + + if (minindex != 0) { + minindex--; + continue; + } + + int avgcount = 1; + std::map::const_iterator n = m_avgcounts.find(i->first); + if (n != m_avgcounts.end()) { + if(n->second >= 1) + avgcount = n->second; + } + o << " " << i->first << ": "; s32 clampsize = 40; - s32 space = clampsize-name.size(); - for(s32 j=0; jfirst.size(); + for(s32 j = 0; j < space; j++) { + if (j % 2 == 0 && j < space - 1) + o << "-"; else - o<<" "; + o << " "; } - o<getValue(); - o<second / avgcount); + o << std::endl; } } + typedef std::map GraphValues; + + void graphAdd(const std::string &id, float value) + { + MutexAutoLock lock(m_mutex); + std::map::iterator i = + m_graphvalues.find(id); + if(i == m_graphvalues.end()) + m_graphvalues[id] = value; + else + i->second += value; + } + void graphGet(GraphValues &result) + { + MutexAutoLock lock(m_mutex); + result = m_graphvalues; + m_graphvalues.clear(); + } + + void remove(const std::string& name) + { + MutexAutoLock lock(m_mutex); + m_avgcounts.erase(name); + m_data.erase(name); + } + private: - JMutex m_mutex; - core::map m_data; + Mutex m_mutex; + std::map m_data; + std::map m_avgcounts; + std::map m_graphvalues; +}; + +enum ScopeProfilerType{ + SPT_ADD, + SPT_AVG, + SPT_GRAPH_ADD }; class ScopeProfiler { public: - ScopeProfiler(Profiler *profiler, const std::string &name): + ScopeProfiler(Profiler *profiler, const std::string &name, + enum ScopeProfilerType type = SPT_ADD): m_profiler(profiler), m_name(name), - m_timer(NULL) + m_timer(NULL), + m_type(type) { if(m_profiler) m_timer = new TimeTaker(m_name.c_str()); } // name is copied - ScopeProfiler(Profiler *profiler, const char *name): + ScopeProfiler(Profiler *profiler, const char *name, + enum ScopeProfilerType type = SPT_ADD): m_profiler(profiler), m_name(name), - m_timer(NULL) + m_timer(NULL), + m_type(type) { if(m_profiler) m_timer = new TimeTaker(m_name.c_str()); @@ -115,9 +217,21 @@ class ScopeProfiler { if(m_timer) { - u32 duration = m_timer->stop(true); - if(m_profiler) - m_profiler->add(m_name, duration); + float duration_ms = m_timer->stop(true); + float duration = duration_ms / 1000.0; + if(m_profiler){ + switch(m_type){ + case SPT_ADD: + m_profiler->add(m_name, duration); + break; + case SPT_AVG: + m_profiler->avg(m_name, duration); + break; + case SPT_GRAPH_ADD: + m_profiler->graphAdd(m_name, duration); + break; + } + } delete m_timer; } } @@ -125,6 +239,7 @@ class ScopeProfiler Profiler *m_profiler; std::string m_name; TimeTaker *m_timer; + enum ScopeProfilerType m_type; }; #endif