Mercurial > hg > octave-nkf
changeset 12920:5d18231eee00
Extend profiling support to operators.
* profiler.h: Always use std::string with profiler name instead of
octave_function references for identifying functions.
* profiler.cc: Adapt for that.
* ov-builtin.cc: Ditto.
* ov-mex-fcn.cc: Ditto.
* ov-usr-fcn.cc: Ditto.
* pt-binop.cc (tree_binary_expression::rvalue1): Collect profiler data.
* pt-unop.cc (tree_prefix_expression::rvalue1): Ditto.
(tree_postfix_expression::rvalue1): Ditto.
author | Daniel Kraft <d@domob.eu> |
---|---|
date | Fri, 29 Jul 2011 17:51:39 +0200 |
parents | 0ca8f06aba7a |
children | 7820a12baadd |
files | src/ov-builtin.cc src/ov-mex-fcn.cc src/ov-usr-fcn.cc src/profiler.cc src/profiler.h src/pt-binop.cc src/pt-unop.cc |
diffstat | 7 files changed, 51 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ov-builtin.cc +++ b/src/ov-builtin.cc @@ -126,7 +126,7 @@ try { - profile_data_accumulator::enter pe (profiler, *this); + profile_data_accumulator::enter pe (profiler, profiler_name ()); retval = (*f) (args, nargout); // Do not allow null values to be returned from functions.
--- a/src/ov-mex-fcn.cc +++ b/src/ov-mex-fcn.cc @@ -148,7 +148,7 @@ try { - profile_data_accumulator::enter pe (profiler, *this); + profile_data_accumulator::enter pe (profiler, profiler_name ()); retval = call_mex (have_fmex, mex_fcn_ptr, args, nargout, this); } catch (octave_execution_exception)
--- a/src/ov-usr-fcn.cc +++ b/src/ov-usr-fcn.cc @@ -135,7 +135,8 @@ tree_evaluator::statement_context = tree_evaluator::script; { - profile_data_accumulator::enter pe (profiler, *this); + profile_data_accumulator::enter pe (profiler, + profiler_name ()); cmd_list->accept (*current_evaluator); } @@ -455,7 +456,7 @@ || cmd_list->is_anon_function_body ()); { - profile_data_accumulator::enter pe (profiler, *this); + profile_data_accumulator::enter pe (profiler, profiler_name ()); if (special_expr) {
--- a/src/profiler.cc +++ b/src/profiler.cc @@ -28,28 +28,27 @@ #include "defun.h" #include "oct-time.h" -#include "ov-fcn.h" #include "ov-struct.h" #include "pager.h" #include "profiler.h" profile_data_accumulator::enter::enter (profile_data_accumulator& a, - const octave_function& f) + const std::string& f) : acc (a) { if (acc.is_active ()) { - fcn = &f; - acc.enter_function (*fcn); + fcn = f; + acc.enter_function (fcn); } else - fcn = NULL; + fcn = ""; } profile_data_accumulator::enter::~enter () { - if (fcn) - acc.exit_function (*fcn); + if (fcn != "") + acc.exit_function (fcn); } profile_data_accumulator::stats::stats () @@ -98,7 +97,7 @@ } void -profile_data_accumulator::enter_function (const octave_function& fcn) +profile_data_accumulator::enter_function (const std::string& fcn) { // The enter class will check and only call us if the profiler is active. assert (is_active ()); @@ -109,33 +108,32 @@ add_current_time (); // Update non-timing related data for the function entered. - const std::string name = fcn.profiler_name (); - stats& entry = data[name]; + stats& entry = data[fcn]; ++entry.calls; if (!call_stack.empty ()) { - const std::string parent_name = call_stack.back ()->profiler_name (); + const std::string parent_name = call_stack.back (); entry.parents.insert (parent_name); - data[parent_name].children.insert (name); + data[parent_name].children.insert (fcn); } if (!entry.recursive) for (call_stack_type::iterator i = call_stack.begin (); i != call_stack.end (); ++i) - if (*i == &fcn) + if (*i == fcn) { entry.recursive = true; break; } - call_stack.push_back (&fcn); + call_stack.push_back (fcn); last_time = query_time (); } void -profile_data_accumulator::exit_function (const octave_function& fcn) +profile_data_accumulator::exit_function (const std::string& fcn) { assert (!call_stack.empty ()); - assert (&fcn == call_stack.back ()); + assert (fcn == call_stack.back ()); // Usually, if we are disabled this function is not even called. But the // call disabling the profiler is an exception. So also check here @@ -229,7 +227,7 @@ assert (last_time >= 0.0 && last_time <= t); assert (!call_stack.empty ()); - const std::string name = call_stack.back ()->profiler_name (); + const std::string name = call_stack.back (); // The entry for this function should already be created; namely // when entering the function via the non-timing data collection!
--- a/src/profiler.h +++ b/src/profiler.h @@ -25,9 +25,9 @@ #include <map> #include <set> +#include <string> #include <vector> -class octave_function; class octave_value; class @@ -44,11 +44,11 @@ profile_data_accumulator& acc; - const octave_function* fcn; + std::string fcn; public: - enter (profile_data_accumulator&, const octave_function& fcn); + enter (profile_data_accumulator&, const std::string&); virtual ~enter (void); @@ -101,7 +101,7 @@ bool enabled; - typedef std::vector<const octave_function*> call_stack_type; + typedef std::vector<std::string> call_stack_type; call_stack_type call_stack; typedef std::map<std::string, stats> stats_map; @@ -112,8 +112,8 @@ // These are private as only the unwind-protecting inner class enter // should be allowed to call them. - void enter_function (const octave_function&); - void exit_function (const octave_function&); + void enter_function (const std::string&); + void exit_function (const std::string&); // Query a timestamp, used for timing calls (obviously). // This is not static because in the future, maybe we want a flag
--- a/src/pt-binop.cc +++ b/src/pt-binop.cc @@ -28,6 +28,7 @@ #include "defun.h" #include "oct-obj.h" #include "ov.h" +#include "profiler.h" #include "pt-binop.h" #include "pt-bp.h" #include "pt-walk.h" @@ -120,6 +121,12 @@ if (! error_state && b.is_defined ()) { + profile_data_accumulator::enter pe (profiler, + "binary " + oper ()); + + /* Note: The profiler does not catch the braindead-short-circuit + evaluation code above. But that should be ok. */ + retval = ::do_binary_op (etype, a, b); if (error_state) @@ -183,6 +190,11 @@ bool result = false; + /* This evaluation is not caught by the profiler, since we can't find + a reasonable place where to time. Note that we don't want to include + evaluation of LHS or RHS into the timing, but this is entangled + together with short-circuit evaluation here. */ + if (op_lhs) { octave_value a = op_lhs->rvalue1 ();
--- a/src/pt-unop.cc +++ b/src/pt-unop.cc @@ -28,6 +28,7 @@ #include "oct-obj.h" #include "oct-lvalue.h" #include "ov.h" +#include "profiler.h" #include "pt-bp.h" #include "pt-unop.h" #include "pt-walk.h" @@ -72,6 +73,9 @@ if (! error_state) { + profile_data_accumulator::enter pe (profiler, + "prefix " + oper ()); + ref.do_unary_op (etype); if (! error_state) @@ -84,6 +88,9 @@ if (! error_state && val.is_defined ()) { + profile_data_accumulator::enter pe (profiler, + "prefix " + oper ()); + // Attempt to do the operation in-place if it is unshared // (a temporary expression). if (val.get_count () == 1) @@ -153,6 +160,9 @@ { retval = ref.value (); + profile_data_accumulator::enter pe (profiler, + "postfix " + oper ()); + ref.do_unary_op (etype); } } @@ -162,6 +172,9 @@ if (! error_state && val.is_defined ()) { + profile_data_accumulator::enter pe (profiler, + "postfix " + oper ()); + retval = ::do_unary_op (etype, val); if (error_state)