From a541c6b0e921681dbabd579b8f2ba712343ddad1 Mon Sep 17 00:00:00 2001
From: Gerardo Tauriello <gerardo.tauriello@unibas.ch>
Date: Mon, 23 May 2016 19:57:57 +0200
Subject: [PATCH] SCHWED-785: added scoped profiler for easier use.
---
core/doc/index.rst | 11 ++++++++
core/pymod/export_runtime_profiling.cc | 11 ++++++++
core/src/runtime_profiling.hh | 39 ++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/core/doc/index.rst b/core/doc/index.rst
index 6de77f72..ba72bef4 100644
--- a/core/doc/index.rst
+++ b/core/doc/index.rst
@@ -110,6 +110,17 @@ Runtime profiling
:param level: Timer only started if level <= ``PM3_RUNTIME_PROFILING_LEVEL``
:type level: :class:`int`
+ .. staticmethod:: StartScoped(id, level=1)
+
+ Start a timer for the given `id` as in :meth:`Start`, but this will stop it
+ automatically when the returned variable goes out of scope.
+
+ :param id: Identifier for this timer.
+ :type id: :class:`str`
+ :param level: Timer only started if level <= ``PM3_RUNTIME_PROFILING_LEVEL``
+ :type level: :class:`int`
+ :return: Object that will call :meth:`Stop` when it goes out of scope
+
.. staticmethod:: Stop(id, level=1)
Stop the currently running timer. If a timer was paused when starting this
diff --git a/core/pymod/export_runtime_profiling.cc b/core/pymod/export_runtime_profiling.cc
index 92918357..5e25ceb8 100644
--- a/core/pymod/export_runtime_profiling.cc
+++ b/core/pymod/export_runtime_profiling.cc
@@ -1,4 +1,7 @@
#include <boost/python.hpp>
+#include <boost/python/register_ptr_to_python.hpp>
+#include <boost/shared_ptr.hpp>
+
#include <promod3/core/runtime_profiling.hh>
using namespace promod3::core;
@@ -9,9 +12,16 @@ bool IsEnabled() { return (PM3_RUNTIME_PROFILING_LEVEL > 0); }
}
void export_runtime_profiling() {
+
+ class_<ScopedRuntimeProfiler>("ScopedRuntimeProfiler", no_init);
+ register_ptr_to_python<ScopedRuntimeProfilerPtr>();
+
class_<StaticRuntimeProfiler>("StaticRuntimeProfiler", no_init)
.def("Start", &StaticRuntimeProfiler::Start, (arg("id"), arg("level")=1))
.staticmethod("Start")
+ .def("StartScoped", &StaticRuntimeProfiler::StartScoped,
+ (arg("id"), arg("level")=1))
+ .staticmethod("StartScoped")
.def("Stop", &StaticRuntimeProfiler::Stop, (arg("level")=1))
.staticmethod("Stop")
.def("PrintSummary", &StaticRuntimeProfiler::PrintSummary)
@@ -19,4 +29,5 @@ void export_runtime_profiling() {
.def("IsEnabled", &IsEnabled)
.staticmethod("IsEnabled")
;
+
}
diff --git a/core/src/runtime_profiling.hh b/core/src/runtime_profiling.hh
index 67930003..3f6d2c42 100644
--- a/core/src/runtime_profiling.hh
+++ b/core/src/runtime_profiling.hh
@@ -8,15 +8,22 @@
#include <iostream>
#include <promod3/config.hh>
#include <ost/base.hh>
+#include <boost/shared_ptr.hpp>
// define dummies if PM3 profiling disabled
#if PM3_RUNTIME_PROFILING_LEVEL==0 || defined(WIN32)
namespace promod3 { namespace core {
+class ScopedRuntimeProfiler { };
+typedef boost::shared_ptr<ScopedRuntimeProfiler> ScopedRuntimeProfilerPtr;
+
class StaticRuntimeProfiler {
public:
static void Start(const String& id, int level=1) { }
+ static ScopedRuntimeProfilerPtr StartScoped(const String& id, int level=1) {
+ return ScopedRuntimeProfilerPtr();
+ }
static void Stop(int level=1) { }
static void PrintSummary() { }
};
@@ -90,6 +97,10 @@ private:
uint num_runs_;
};
+// fw decl. needed for RuntimeProfiler
+class ScopedRuntimeProfiler;
+typedef boost::shared_ptr<ScopedRuntimeProfiler> ScopedRuntimeProfilerPtr;
+
/// \brief Keep track of multiple profiled entried (identified by a String).
///
/// Usage:
@@ -123,6 +134,8 @@ public:
watches_.back().second.Start();
}
+ ScopedRuntimeProfilerPtr StartScoped(const String& id);
+
// note: no check done! Something must have been running!
void Stop() {
// stop whatever is running
@@ -187,6 +200,25 @@ private:
std::vector< std::pair<RuntimeProfilerEntry*, Stopwatch> > watches_;
};
+/// \brief Helper for StartScoped
+class ScopedRuntimeProfiler {
+public:
+ ScopedRuntimeProfiler(RuntimeProfiler* rp, const String& id) {
+ rp_ = rp;
+ rp->Start(id);
+ }
+ ~ScopedRuntimeProfiler() {
+ rp_->Stop();
+ }
+private:
+ RuntimeProfiler* rp_;
+};
+
+// circular use RuntimeProfiler<->ScopedRuntimeProfiler, this must be here!
+inline ScopedRuntimeProfilerPtr RuntimeProfiler::StartScoped(const String& id) {
+ return ScopedRuntimeProfilerPtr(new ScopedRuntimeProfiler(this, id));
+}
+
/// \brief Wrapper for RuntimeProfiler with static access.
/// This makes sure we can remove all profiling stuff at compile-time.
class StaticRuntimeProfiler {
@@ -194,6 +226,13 @@ public:
static void Start(const String& id, int level=1) {
if (level <= PM3_RUNTIME_PROFILING_LEVEL) { GetInstance_().Start(id); }
}
+ static ScopedRuntimeProfilerPtr StartScoped(const String& id, int level=1) {
+ if (level <= PM3_RUNTIME_PROFILING_LEVEL) {
+ return GetInstance_().StartScoped(id);
+ } else {
+ return ScopedRuntimeProfilerPtr();
+ }
+ }
static void Stop(int level=1) {
if (level <= PM3_RUNTIME_PROFILING_LEVEL) { GetInstance_().Stop(); }
}
--
GitLab