52 #include <boost/intrusive_ptr.hpp> 53 #include <boost/timer/timer.hpp> 60 #if defined(PROFINY_CALL_GRAPH_PROFILER) && defined(PROFINY_FLAT_PROFILER) 62 #error "PROFINY_CALL_GRAPH_PROFILER and PROFINY_FLAT_PROFILER should not be defined at the same time!" 64 #elif defined(PROFINY_CALL_GRAPH_PROFILER) || defined(PROFINY_FLAT_PROFILER) 66 #define PROFINY_SCOPE \ 67 std::ostringstream _oss; \ 68 _oss << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__; \ 69 profiny::ScopedProfile _sco_pro(_oss.str()); 71 #define PROFINY_SCOPE_WITH_ID(ID) \ 72 std::ostringstream _oss; \ 73 _oss << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":" << (ID); \ 74 profiny::ScopedProfile _sco_pro(_oss.str()); 76 #define PROFINY_NAMED_SCOPE(NAME) \ 77 std::ostringstream _oss; \ 79 profiny::ScopedProfile _sco_pro(_oss.str()); 81 #define PROFINY_NAMED_SCOPE_WITH_ID(NAME, ID) \ 82 std::ostringstream _oss; \ 83 _oss << (NAME) << ":" << (ID); \ 84 profiny::ScopedProfile _sco_pro(_oss.str()); 90 #define PROFINY_SCOPE_WITH_ID(ID) 92 #define PROFINY_NAMED_SCOPE(NAME) 94 #define PROFINY_NAMED_SCOPE_WITH_ID(NAME, ID) 99 #define NANOSEC_TO_SEC(X) ((X) / 1000000000.0) 109 virtual ~BaseObject();
123 class Profile :
public BaseObject
125 friend class ScopedProfile;
126 friend class Profiler;
129 Profile(
const std::string&
name);
137 unsigned int getCallCount()
const;
139 std::string getName()
const;
141 void getTimes(
double& wall,
double& user,
double& system)
const;
143 #ifdef PROFINY_CALL_GRAPH_PROFILER 144 std::map<std::string, boost::intrusive_ptr<Profile> >& getSubProfiles();
146 std::map<std::string, boost::intrusive_ptr<Profile> > m_subProfiles;
153 unsigned int m_callCount;
159 boost::timer::cpu_timer m_timer;
164 class ScopedProfile :
public BaseObject
167 ScopedProfile(
const std::string&
name);
172 boost::intrusive_ptr<Profile> m_profile;
177 class Profiler :
public BaseObject
179 friend class Profile;
180 friend class ScopedProfile;
183 static void printStats(
const std::string&
filename);
185 #ifdef PROFINY_CALL_GRAPH_PROFILER 186 static void setOmitRecursiveCalls(
bool omit);
188 static bool getOmitRecursiveCalls();
196 static boost::intrusive_ptr<Profiler> getInstance();
198 boost::intrusive_ptr<Profile> getProfile(
const std::string&
name);
200 static void printStats();
202 static void printStats(std::ofstream& fs, std::map<std::string, boost::intrusive_ptr<Profile> >* p,
int depth);
204 #ifdef PROFINY_CALL_GRAPH_PROFILER 205 std::map<std::string, boost::intrusive_ptr<Profile> >& getCurrentProfilesRoot();
207 void pushProfile(boost::intrusive_ptr<Profile> p);
211 bool isInStack(
const std::string&
name);
214 std::map<std::string, boost::intrusive_ptr<Profile> > m_profiles;
216 static boost::intrusive_ptr<Profiler> m_instance;
218 #ifdef PROFINY_CALL_GRAPH_PROFILER 219 std::vector<boost::intrusive_ptr<Profile> > m_profileStack;
221 bool m_omitRecursiveCalls;
227 inline BaseObject::BaseObject() : m_ref(0)
231 inline BaseObject::~BaseObject()
235 inline void BaseObject::incrRef()
240 inline void BaseObject::decrRef()
245 inline int BaseObject::getRef()
const 252 inline Profile::Profile(
const std::string&
name)
254 #ifndef PROFINY_CALL_GRAPH_PROFILER 266 inline Profile::~Profile()
270 inline bool Profile::start()
272 #ifdef PROFINY_CALL_GRAPH_PROFILER 273 Profiler::getInstance()->pushProfile(
this);
279 m_timeStarted =
true;
285 inline bool Profile::stop()
287 #ifdef PROFINY_CALL_GRAPH_PROFILER 288 Profiler::getInstance()->popProfile();
294 m_timeStarted =
false;
297 boost::timer::cpu_times t = m_timer.elapsed();
305 inline unsigned int Profile::getCallCount()
const 310 inline std::string Profile::getName()
const 315 inline void Profile::getTimes(
double& wall,
double& user,
double& system)
const 319 system = m_systemTime;
322 #ifdef PROFINY_CALL_GRAPH_PROFILER 323 inline std::map<std::string, boost::intrusive_ptr<Profile> >& Profile::getSubProfiles()
325 return m_subProfiles;
331 inline ScopedProfile::ScopedProfile(
const std::string&
name)
335 #ifdef PROFINY_CALL_GRAPH_PROFILER 336 if (Profiler::getInstance()->isInStack(n))
338 if (Profiler::getInstance()->getOmitRecursiveCalls())
345 n =
"RECURSIVE@" + n;
350 m_profile = Profiler::getInstance()->getProfile(n);
351 if (m_profile != NULL)
353 if (!m_profile->start())
360 std::cerr <<
"Cannot start scoped profiler: " << n << std::endl;
364 inline ScopedProfile::~ScopedProfile()
366 if (m_profile != NULL)
374 boost::intrusive_ptr<Profiler> Profiler::m_instance = NULL;
376 inline Profiler::Profiler()
377 #ifdef PROFINY_CALL_GRAPH_PROFILER 378 : m_omitRecursiveCalls(
true)
383 inline Profiler::~Profiler()
387 inline boost::intrusive_ptr<Profiler> Profiler::getInstance()
389 if (m_instance == NULL)
391 m_instance =
new Profiler;
397 inline boost::intrusive_ptr<Profile> Profiler::getProfile(
const std::string&
name)
399 #ifdef PROFINY_CALL_GRAPH_PROFILER 400 std::map<std::string, boost::intrusive_ptr<Profile> >& profiles = getCurrentProfilesRoot();
402 std::map<std::string, boost::intrusive_ptr<Profile> >& profiles = m_profiles;
404 std::map<std::string, boost::intrusive_ptr<Profile> >::iterator it = profiles.find(
name);
405 if (it != profiles.end())
411 boost::intrusive_ptr<Profile> result =
new Profile(
name);
412 profiles[
name] = result;
417 #ifdef PROFINY_CALL_GRAPH_PROFILER 418 inline std::map<std::string, boost::intrusive_ptr<Profile> >& Profiler::getCurrentProfilesRoot()
420 return m_profileStack.empty() ? m_profiles : m_profileStack.back()->getSubProfiles();
423 inline void Profiler::pushProfile(boost::intrusive_ptr<Profile> p)
425 m_profileStack.push_back(p);
428 inline void Profiler::popProfile()
430 if (!m_profileStack.empty())
432 m_profileStack.pop_back();
436 inline bool Profiler::isInStack(
const std::string&
name)
438 for (
unsigned int i = 0; i < m_profileStack.size(); i++)
440 if (m_profileStack[i]->getName() ==
name)
449 inline void Profiler::printStats(std::ofstream& fs, std::map<std::string, boost::intrusive_ptr<Profile> >* p,
int depth)
451 #ifdef PROFINY_CALL_GRAPH_PROFILER 452 std::ostringstream oss;
453 for (
int i = 0; i < depth; i++)
459 std::map<std::string, boost::intrusive_ptr<Profile> >::iterator it = p->begin();
460 for (; it != p->end(); it++)
462 unsigned int cc = it->second->getCallCount();
463 double wall, user, system;
464 it->second->getTimes(wall, user, system);
465 #ifdef PROFINY_CALL_GRAPH_PROFILER 466 fs << oss.str() << it->second->getName() <<
" T:" << wall <<
" #:" << cc <<
" %:" << 100 * ((user + system) / wall) << std::endl;
467 printStats(fs, &(it->second->getSubProfiles()), depth + 1);
469 fs << it->second->getName() <<
" T:" << wall <<
" #:" << cc <<
" %:" << 100 * ((user + system) / wall) << std::endl;
474 inline void Profiler::printStats()
476 printStats(
"profiny.out");
479 inline void Profiler::printStats(
const std::string&
filename)
485 std::cerr <<
"Cannot open profiler output file: " <<
filename << std::endl;
488 Profiler::printStats(fs, &(getInstance()->m_profiles), 0);
492 #ifdef PROFINY_CALL_GRAPH_PROFILER 493 inline void Profiler::setOmitRecursiveCalls(
bool omit)
495 getInstance()->m_omitRecursiveCalls = omit;
498 inline bool Profiler::getOmitRecursiveCalls()
500 return getInstance()->m_omitRecursiveCalls;
521 if (p->getRef() <= 0)
Core::PropertyText name
Definition: CoreDocument.h:143
void intrusive_ptr_release(profiny::BaseObject *p)
Definition: Profiny.h:516
Core::PropertyText filename
Definition: CoreDocument.h:151
#define NANOSEC_TO_SEC(X)
Definition: Profiny.h:99
void intrusive_ptr_add_ref(profiny::BaseObject *p)
Definition: Profiny.h:508