Skip to content

Commit

Permalink
Added docs for inverted flame graph
Browse files Browse the repository at this point in the history
Added documentation that explains an inverted flame graph.

Signed-off-by: Ivona Stojanovic <[email protected]>
  • Loading branch information
ivonastojanovic committed Aug 21, 2023
1 parent a65cd31 commit 4fa798a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions docs/flamegraph.rst
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,84 @@ dropdown menu.
Note that the root node (displayed as **<root>**) is always present
and is displayed as thread 0.

.. _inverted flame graphs:

Inverted flame graphs
------------------

In a normal flame graph, the roots are thread entry points and
the children of any given node are the functions called by that node,
and the leaf nodes are functions that allocated memory but did not call any
functions that allocated memory. This can result in duplicated leaf nodes,
if there are multiple call stacks that lead to a particular function that
performs allocations.

When generating flame graphs, the ``--inverted`` option can be
specified to get an inverted flame graph.

In an inverted flame graph, the roots are the functions that allocated memory,
and the children of any given node represent the percentage of any of that node's
allocations that can be attributed to a particular caller.

The inverted flame graph is very helpful in analyzing where memory is being
spent in aggregate. If a function that allocates memory is called from multiple places,
in the normal flame graph it will show up multiple times in the leaves, but in the inverted
flame graph, all calls to one function will be aggregated.

Simple example
--------------

.. code:: python
def a():
return 1000000 * "a"
def a1():
return 1000000 * "a"
def b():
return a()
def c():
return b()
def d():
return b()
def f():
return g()
def e():
return g()
def g():
return c()
def main():
a = a1()
x = d()
y = e()
z = f()
return (x,y,z,a)
main()
This code allocates memory from the system allocator in just 2 places: ``a()``, and ``a1()``.
This is how the normal frame graph looks like:

.. image:: _static/images/normal_flamegraph_for_inverted_example.png

Here you can see that ``a()`` allocated memory three times when it is called from ``b()``, and
``a1()`` allocates memory when it is called from ``main()``.

If we generate the inverted flame graph with ``--inverted``, the flame graph looks like this:

.. image:: _static/images/inverted_flame_graph_for_inverted_example.png

Here you can see that we have ``return 1000000 * "a"`` as a root two times, the first one allocates more memory
because ``a()`` is called three times from ``b()``, and the other ``return 1000000 * "a"`` is called once from ``main()`` once.

.. _temporal flame graphs:

Temporal Flame Graphs
Expand Down

0 comments on commit 4fa798a

Please sign in to comment.