aboutsummaryrefslogtreecommitdiffstats
path: root/docs/doxygen/other/perf_counters.dox
blob: 9bca38268a253d0b93c3c41db268a8e5e9d520cd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*! \page page_perf_counters Performance Counters

\section pc_introduction Introduction

Each block can have a set of Performance Counters that the schedule
keeps track of. These counters measure and store information about
different performance metrics of their operation. The concept is
fairly extensible, but currently, GNU Radio defines the following
Performance Counters:

\li noutput_items: number of items the block can produce.
\li nproduced: the number of items the block produced.
\li input_buffers_full: % of how full each input buffer is.
\li output_buffers_full: % of how full each output buffer is.
\li work_time: number of CPU ticks during the call to general_work().
\li work_time_total: Accumulated sum of work_time.

For each Performance Counter except the work_time_total, we can
retrieve the instantaneous, average, and variance from the
block. Access to these counters is done through a simple set of
functions added to every block in the flowgraph:

\code
  float pc_<name>[_<type>]();
\endcode

In the above, the \<name\> field is one of the counters in the above
list of counters. The optional \<type\> suffix is either 'avg' to get
the average value or 'var' to get the variance. Without a suffix, the
function returns the most recent instantaneous value.

We can also reset the Performance Counters back to zero to remove any
history of the current average and variance calculations for a
particular block.

\code
  void reset_perf_counters();
\endcode


\section pc_config Compile-time and Run-time Configuration

Because the Performance Counters are calculated during each call to
work for every block, they increase the computational cost and memory
overhead. The more blocks used, the more impact this may have. So
while it turns out after some experimentation that the Performance
Counters add very little overhead (less than 1% speed degradation for
a 24-block flowgraph), we err on the side of minimizing overhead in
the scheduler. To do so, we have added compile-time and run-time
configuration of the use of Performance Counters.


\subsection pc_config_compile Compile-time Config

By default, GNU Radio will build without Performance Counters
enabled. To enable Performance Counters, we pass the following flag to
cmake:

\code
  -DENABLE_PERFORMANCE_COUNTERS=True
\endcode

Note that this affects the GNU Radio block class and the scheduler
itself. Out-of-tree projects will inherit directly from GNU Radio
because of the inheritance with gr::block. Turning on Performance
Counters for GNU Radio will require a recompilation of the OOT project
but no extra configuration.


\subsection pc_config_runtime Run-time Config

Given the Performance Counters are enabled in GNU Radio at
compile-time, we can still control if they are used or not at
run-time. For this, we use the GNU Radio preferences file in the
section [PerfCounters]. This section is installed into the
gnuradio-runtime.conf file. As usual with the preferences, this
section or any of the individual options can be overridden in the
user's config.conf file or using a GR_CONF_ environmental variable
(see \ref prefs for more details).

The options for the [PerfCounters] section are:

\li on: Turn counters on/off at run-time.
\li export: Allow counters to be exported over ControlPort.
\li clock: sets the type of clock used when calculating work_time
('thread' or 'monotonic').


\section pc_perfmonitor Performance Monitor

See \ref perfmonitor for some details of using a ControlPort-based
monitor application, gr-perf-monitorx, for visualizing the
counters. This application is particularly useful in learning which
blocks are the computationally complex blocks that could use extra
optimization or work to improve their performance. It can also be used
to understand the current 'health' of the application.

*/