Profiling with FlameGraph (Linux)

1. Get FlameGraph

git clone https://github.com/brendangregg/FlameGraph

It’s a tool from Brendan Gregg.


2. Build the app

#include <iostream>
#include <cmath>

void wasteTime()
{
    std::cout << "Start calculating" << std::endl;
    volatile double result = 0.0;
    for (int i = 0; i < 1'000; ++i)
    {
        for (int j = 0; j < 1'000; ++j)
        {
            result += std::sin(i) * std::cos(j);
        }
    }
    std::cout << "Result: " << result << std::endl;
}

int main()
{
    wasteTime();
    return 0;
}
$ g++ main.cpp -g

3. Record execution

$ sudo perf record -F 99 -a -g ./a.out
Start calculating
Result: -0.012595
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 1,005 MB perf.data (53 samples) ]
  • F … Profiles at this frequency
  • a … Collects from all CPUs
  • g … Enables the call-graph

4. Create flame graph

$ sudo perf script | ~/FlameGraph/stackcollapse-perf.pl | ~/FlameGraph/flamegraph.pl > flamegraph.svg


5. Interpretation

  • x-axis: Shows what has been called for how long. (Not ordered by time.)
  • y-axis: Shows what has been called at what depth. (Based on call-stack.)

This application takes 22.64% and its “wasteTime” function takes 20.75% of the whole CPU usage.

22,64 * x = 100
x = 100 / 22,64
x = 4,41696113
y = 20,75 * x
y = 91,65194346

Based on that calculation, we now know that 91.65% of our application gets used by “wasteTime”.