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”.