Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 18 additions & 71 deletions doc/services/profiling/perf.rst
Original file line number Diff line number Diff line change
@@ -1,91 +1,38 @@
.. _profiling-perf:


Perf
####

Perf is a profiler tool based on stack tracing. It can be used for lightweight profiling
with minimal code overhead.

Perf is a profiler tool, based on stack tracing. It can be used to light weight profiling
almost without any code overhead.

Work principe
*************
Work Principle
**************

``perf record`` shell-command starts timer with perf tracer function.
Timers are driven by inerrupts, so perf tracer function is calling during interruption.
Zephyr core save return address and frame pointer in interrupt stack or ``callee_saved``
struture before caling interrupt hundler. So perf trace function makes stack traces by
using return address and frame pointer.
The ``perf record`` shell command starts a timer with the perf tracer function.
Timers are driven by interrupts, so the perf tracer function is called during an interruption.
The Zephyr core saves the return address and frame pointer in the interrupt stack or ``callee_saved``
structure before calling the interrupt handler. Thus, the perf trace function makes stack traces by
using the return address and frame pointer.

Then stackcollapse.py script convert return addresses in stack trace to function names
by elf file and print them in required for FlameGraph format.
The :zephyr_file:`scripts/profiling/stackcollapse.py` script can be used to convert return addresses
in the stack trace to function names using symbols from the ELF file, and to prints them in the
format expected by `FlameGraph`_.

Configuration
*************

Configure this module using the following options.
You can configure this module using the following options:

* :kconfig:option:`CONFIG_PROFILING_PERF`: enable the module. This opion add
perf command in shell.
* :kconfig:option:`CONFIG_PROFILING_PERF`: Enables the module. This option adds
the ``perf`` command to the shell.

* :kconfig:option:`CONFIG_PROFILING_PERF_BUFFER_SIZE`: sets size of perf buffer,
* :kconfig:option:`CONFIG_PROFILING_PERF_BUFFER_SIZE`: Sets the size of the perf buffer
where samples are saved before printing.

Usage
*****

More specific example can be found in :zephyr:code-sample:`profiling-perf`.

#. Build with perf enabled and run.

#. Begin perf sampling by shell-command

.. code-block:: text

perf record <period> <frequency>

This command will start timer with perf sampler for *period* in seconds and
with *frequency* in hertz.

Wait for the completion message ``perf done!`` or ``perf buf override!``
(if perf buffer size is smaller than required).

#. Print made by perf samles in terminal by shell-command

.. code-block:: text

perf printbuf

Output exaple:

.. code-block:: text

Perf buf length 1985
0000000000000004
0000000080004e58
00000000800071ca
0000000080000964
aaaaaaaaaaaaaaaa
0000000000000002
....
00000000800163e0

Copy gotten output in some file, for example *perf_buf*.

#. Translate perf samples by stackcollapse script to format, required by FlameGraph

.. code-block:: bash

python zephyr/scripts/perf/stackcollapse.py perf_buf <build_dir>/zephyr/zephyr.elf > perf_buf.folded

And turn into .svg FlameGraph (for example *graph.svg*)

.. code-block:: bash

./FlameGraph/flamegraph.pl perf_buf.folded > graph.svg

All this step can be done by one command

.. code-block:: bash
Refer to the :zephyr:code-sample:`profiling-perf` sample for an example of how to use the perf tool.

python zephyr/scripts/perf/stackcollapse.py perf_buf <build_dir>/zephyr/zephyr.elf | ./FlameGraph/flamegraph.pl > graph.svg
.. _FlameGraph: https://github.com/brendangregg/FlameGraph/
73 changes: 38 additions & 35 deletions samples/subsys/profiling/perf/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,70 @@

Send perf samples to the host with console support

This application can be used to demonstrate :ref:`profiling-perf` work.
This application can be used to understand how to use the :ref:`profiling-perf`
tool.

Requirements
************

Perf tool so far implemente only for riscv and x86_64 architectures.
The Perf tool is currently implemented only for RISC-V and x86_64 architectures.

Usage example
*************

Build an image with:
* Build and run the sample with:

.. zephyr-app-commands::
:zephyr-app: samples/subsys/profiling/perf
:board: qemu_riscv64
:goals: build
:compact:
.. zephyr-app-commands::
:zephyr-app: samples/subsys/profiling/perf
:board: qemu_riscv64
:goals: run
:compact:

After the sample starts, enter shell command:
* After the sample has started, enter the shell command:

.. code-block:: console
.. code-block:: console

uart:~$ perf record <period> <frequency>
uart:~$ perf record <duration> <frequency>

Wait for the completion message ``perf done!`` or ``perf buf override!``
(if perf buffer size is smaller than required).
This command will start a timer for *duration* milliseconds at *frequency* Hz.

Print made by perf samles in terminal by shell-command:
* Wait for the completion message ``perf done!``, or ``perf buf override!`` if
the perf buffer size is smaller than required.

.. code-block:: console
* Print the samples captured by perf in the terminal with the shell command:

uart:~$ perf printbuf
.. code-block:: console

Output exaple:
uart:~$ perf printbuf

.. code-block:: console
The output should be similar to:

Perf buf length 2046
0000000000000004
00000000001056b2
0000000000108192
000000000010052f
0000000000000000
....
000000000010052f
0000000000000000
.. code-block:: console

Copy gotten output in some file, for example *perf_buf*.
Perf buf length 2046
0000000000000004
00000000001056b2
0000000000108192
000000000010052f
0000000000000000
....
000000000010052f
0000000000000000

Make graph.svg with :zephyr_file:`scripts/perf/stackcollapse.py` and
`FlameGraph`_:
* Copy the output into a file, for example :file:`perf_buf`.

.. _FlameGraph: https://github.com/brendangregg/FlameGraph/
* Generate :file:`graph.svg` with
:zephyr_file:`scripts/profiling/stackcollapse.py` and `FlameGraph`_:

.. code-block:: shell
.. _FlameGraph: https://github.com/brendangregg/FlameGraph/

python scripts/perf/stackcollapse.py perf_buf build/zephyr/zephyr.elf | <flamegraph_dir_path>/flamegraph.pl > graph.svg
.. code-block:: shell

python scripts/perf/stackcollapse.py perf_buf build/zephyr/zephyr.elf | <flamegraph_dir_path>/flamegraph.pl > graph.svg

Graph example
=============

.. image:: images/graph_example.svg
:align: center
:alt: graph example
:align: center
:alt: graph example
2 changes: 1 addition & 1 deletion subsys/profiling/perf/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ config PROFILING_PERF_BUFFER_SIZE
int "Perf buffer size"
default 2048
help
Size of buffer, that used by perf to save samples from stack tracing.
Size of buffer used by perf to save stack trace samples.

endif