diff options
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block.cc | 85 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block.h | 41 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block_detail.cc | 137 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_block_detail.h | 15 |
4 files changed, 260 insertions, 18 deletions
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc index f52f7a6ba..54d267620 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_block.cc @@ -282,6 +282,17 @@ gr_block::pc_noutput_items() } float +gr_block::pc_noutput_items_var() +{ + if(d_detail) { + return d_detail->pc_noutput_items_var(); + } + else { + return 0; + } +} + +float gr_block::pc_nproduced() { if(d_detail) { @@ -293,6 +304,17 @@ gr_block::pc_nproduced() } float +gr_block::pc_nproduced_var() +{ + if(d_detail) { + return d_detail->pc_nproduced_var(); + } + else { + return 0; + } +} + +float gr_block::pc_input_buffers_full(int which) { if(d_detail) { @@ -303,6 +325,17 @@ gr_block::pc_input_buffers_full(int which) } } +float +gr_block::pc_input_buffers_full_var(int which) +{ + if(d_detail) { + return d_detail->pc_input_buffers_full_var(static_cast<size_t>(which)); + } + else { + return 0; + } +} + std::vector<float> gr_block::pc_input_buffers_full() { @@ -314,6 +347,17 @@ gr_block::pc_input_buffers_full() } } +std::vector<float> +gr_block::pc_input_buffers_full_var() +{ + if(d_detail) { + return d_detail->pc_input_buffers_full_var(); + } + else { + return std::vector<float>(1,0); + } +} + float gr_block::pc_output_buffers_full(int which) { @@ -325,6 +369,17 @@ gr_block::pc_output_buffers_full(int which) } } +float +gr_block::pc_output_buffers_full_var(int which) +{ + if(d_detail) { + return d_detail->pc_output_buffers_full_var(static_cast<size_t>(which)); + } + else { + return 0; + } +} + std::vector<float> gr_block::pc_output_buffers_full() { @@ -336,6 +391,17 @@ gr_block::pc_output_buffers_full() } } +std::vector<float> +gr_block::pc_output_buffers_full_var() +{ + if(d_detail) { + return d_detail->pc_output_buffers_full_var(); + } + else { + return std::vector<float>(1,0); + } +} + float gr_block::pc_work_time() { @@ -347,6 +413,25 @@ gr_block::pc_work_time() } } +float +gr_block::pc_work_time_var() +{ + if(d_detail) { + return d_detail->pc_work_time_var(); + } + else { + return 0; + } +} + +void +gr_block::reset_perf_counters() +{ + if(d_detail) { + d_detail->reset_perf_counters(); + } +} + std::ostream& operator << (std::ostream& os, const gr_block *m) { diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h index bd9ff42df..6e21d5b97 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.h +++ b/gnuradio-core/src/lib/runtime/gr_block.h @@ -383,35 +383,74 @@ class GR_CORE_API gr_block : public gr_basic_block { float pc_noutput_items(); /*! + * \brief Gets variance of noutput_items performance counter. + */ + float pc_noutput_items_var(); + + /*! * \brief Gets average num items produced performance counter. */ float pc_nproduced(); /*! - * \brief Gets average average fullness of \p which input buffer. + * \brief Gets variance of num items produced performance counter. + */ + float pc_nproduced_var(); + + /*! + * \brief Gets average fullness of \p which input buffer. */ float pc_input_buffers_full(int which); /*! + * \brief Gets variance of fullness of \p which input buffer. + */ + float pc_input_buffers_full_var(int which); + + /*! * \brief Gets average fullness of all input buffers. */ std::vector<float> pc_input_buffers_full(); /*! + * \brief Gets variance of fullness of all input buffers. + */ + std::vector<float> pc_input_buffers_full_var(); + + /*! * \brief Gets average fullness of \p which input buffer. */ float pc_output_buffers_full(int which); /*! + * \brief Gets variance of fullness of \p which input buffer. + */ + float pc_output_buffers_full_var(int which); + + /*! * \brief Gets average fullness of all output buffers. */ std::vector<float> pc_output_buffers_full(); + /*! + * \brief Gets variance of fullness of all output buffers. + */ + std::vector<float> pc_output_buffers_full_var(); /*! * \brief Gets average clock cycles spent in work. */ float pc_work_time(); + /*! + * \brief Gets average clock cycles spent in work. + */ + float pc_work_time_var(); + + /*! + * \brief Resets the performance counters + */ + void reset_perf_counters(); + // ---------------------------------------------------------------------------- // Functions to handle thread affinity diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc index ff20e0e85..82081039a 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc @@ -43,10 +43,17 @@ gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs) d_ninputs (ninputs), d_noutputs (noutputs), d_input (ninputs), d_output (noutputs), d_done (false), - d_avg_noutput_items(0), d_avg_nproduced(0), + d_avg_noutput_items(0), + d_var_noutput_items(0), + d_avg_nproduced(0), + d_var_nproduced(0), d_avg_input_buffers_full(ninputs, 0), + d_var_input_buffers_full(ninputs, 0), d_avg_output_buffers_full(noutputs, 0), - d_avg_work_time(0) + d_var_output_buffers_full(noutputs, 0), + d_avg_work_time(0), + d_var_work_time(0), + d_pc_counter(0) { s_ncurrently_allocated++; } @@ -237,27 +244,68 @@ gr_block_detail::start_perf_counters() void gr_block_detail::stop_perf_counters(int noutput_items, int nproduced) { - float alpha = 0.05; - float beta = 1.0-alpha; - d_end_of_work = gruel::high_res_timer_now(); gruel::high_res_timer_type diff = d_end_of_work - d_start_of_work; - d_avg_work_time = beta*d_avg_work_time + alpha*diff; - - d_avg_nproduced = beta*d_avg_nproduced + alpha*nproduced; - d_avg_noutput_items = beta*d_avg_noutput_items + alpha*noutput_items; - for(size_t i=0; i < d_input.size(); i++) { - float pfull = static_cast<float>(d_input[i]->items_available()) / - static_cast<float>(d_input[i]->max_possible_items_available()); - d_avg_input_buffers_full[i] = beta*d_avg_input_buffers_full[i] + alpha*pfull; + if(d_pc_counter == 0) { + d_avg_work_time = diff; + d_var_work_time = 0; + d_avg_nproduced = nproduced; + d_var_nproduced = 0; + d_avg_noutput_items = noutput_items; + d_var_noutput_items = 0; + for(size_t i=0; i < d_input.size(); i++) { + float pfull = static_cast<float>(d_input[i]->items_available()) / + static_cast<float>(d_input[i]->max_possible_items_available()); + d_avg_input_buffers_full[i] = pfull; + d_var_input_buffers_full[i] = 0; + } + for(size_t i=0; i < d_output.size(); i++) { + float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) / + static_cast<float>(d_output[i]->bufsize()); + d_avg_output_buffers_full[i] = pfull; + d_var_output_buffers_full[i] = 0; + } } + else { + float d = diff - d_avg_work_time; + d_avg_work_time = d_avg_work_time + d/d_pc_counter; + d_var_work_time = d_var_work_time + d*d; + + d = nproduced - d_avg_nproduced; + d_avg_nproduced = d_avg_nproduced + d/d_pc_counter; + d_var_nproduced = d_var_nproduced + d*d; + + d = noutput_items - d_avg_noutput_items; + d_avg_noutput_items = d_avg_noutput_items + d/d_pc_counter; + d_var_noutput_items = d_var_noutput_items + d*d; + + for(size_t i=0; i < d_input.size(); i++) { + float pfull = static_cast<float>(d_input[i]->items_available()) / + static_cast<float>(d_input[i]->max_possible_items_available()); + + d = pfull - d_avg_input_buffers_full[i]; + d_avg_input_buffers_full[i] = d_avg_input_buffers_full[i] + d/d_pc_counter; + d_var_input_buffers_full[i] = d_var_input_buffers_full[i] + d*d; + } - for(size_t i=0; i < d_output.size(); i++) { - float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) / - static_cast<float>(d_output[i]->bufsize()); - d_avg_output_buffers_full[i] = beta*d_avg_output_buffers_full[i] + alpha*pfull; + for(size_t i=0; i < d_output.size(); i++) { + float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) / + static_cast<float>(d_output[i]->bufsize()); + + d = pfull - d_avg_output_buffers_full[i]; + d_avg_output_buffers_full[i] = d_avg_output_buffers_full[i] + d/d_pc_counter; + d_var_output_buffers_full[i] = d_var_output_buffers_full[i] + d*d; + } } + + d_pc_counter++; +} + +void +gr_block_detail::reset_perf_counters() +{ + d_pc_counter = 0; } float @@ -307,3 +355,58 @@ gr_block_detail::pc_work_time() { return d_avg_work_time; } + + +float +gr_block_detail::pc_noutput_items_var() +{ + return d_var_noutput_items/(d_pc_counter-1); +} + +float +gr_block_detail::pc_nproduced_var() +{ + return d_var_nproduced/(d_pc_counter-1); +} + +float +gr_block_detail::pc_input_buffers_full_var(size_t which) +{ + if(which < d_avg_input_buffers_full.size()) + return d_var_input_buffers_full[which]/(d_pc_counter-1); + else + return 0; +} + +std::vector<float> +gr_block_detail::pc_input_buffers_full_var() +{ + std::vector<float> var(d_avg_input_buffers_full.size(), 0); + for(size_t i = 0; i < d_avg_input_buffers_full.size(); i++) + var[i] = d_avg_input_buffers_full[i]/(d_pc_counter-1); + return var; +} + +float +gr_block_detail::pc_output_buffers_full_var(size_t which) +{ + if(which < d_avg_output_buffers_full.size()) + return d_var_output_buffers_full[which]/(d_pc_counter-1); + else + return 0; +} + +std::vector<float> +gr_block_detail::pc_output_buffers_full_var() +{ + std::vector<float> var(d_avg_output_buffers_full.size(), 0); + for(size_t i = 0; i < d_avg_output_buffers_full.size(); i++) + var[i] = d_avg_output_buffers_full[i]/(d_pc_counter-1); + return var; +} + +float +gr_block_detail::pc_work_time_var() +{ + return d_var_work_time/(d_pc_counter-1); +} diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h index a8ed8da90..32a01e763 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h @@ -173,6 +173,7 @@ class GR_CORE_API gr_block_detail { void start_perf_counters(); void stop_perf_counters(int noutput_items, int nproduced); + void reset_perf_counters(); // Calls to get performance counter items float pc_noutput_items(); @@ -182,6 +183,14 @@ class GR_CORE_API gr_block_detail { float pc_output_buffers_full(size_t which); std::vector<float> pc_output_buffers_full(); float pc_work_time(); + + float pc_noutput_items_var(); + float pc_nproduced_var(); + float pc_input_buffers_full_var(size_t which); + std::vector<float> pc_input_buffers_full_var(); + float pc_output_buffers_full_var(size_t which); + std::vector<float> pc_output_buffers_full_var(); + float pc_work_time_var(); gr_tpb_detail d_tpb; // used by thread-per-block scheduler int d_produce_or; @@ -197,11 +206,17 @@ class GR_CORE_API gr_block_detail { // Performance counters float d_avg_noutput_items; + float d_var_noutput_items; float d_avg_nproduced; + float d_var_nproduced; std::vector<float> d_avg_input_buffers_full; + std::vector<float> d_var_input_buffers_full; std::vector<float> d_avg_output_buffers_full; + std::vector<float> d_var_output_buffers_full; gruel::high_res_timer_type d_start_of_work, d_end_of_work; float d_avg_work_time; + float d_var_work_time; + float d_pc_counter; gr_block_detail (unsigned int ninputs, unsigned int noutputs); |