{"id":18216,"date":"2025-01-22T17:07:08","date_gmt":"2025-01-22T17:07:08","guid":{"rendered":"http:\/\/www.max-sperling.bplaced.net\/?p=18216"},"modified":"2025-05-14T12:35:24","modified_gmt":"2025-05-14T12:35:24","slug":"profiling-with-flamegraph-linux","status":"publish","type":"post","link":"http:\/\/www.max-sperling.bplaced.net\/?p=18216","title":{"rendered":"FlameGraph (Docker)"},"content":{"rendered":"<h2>Setup<\/h2>\n<ol>\n<li>Get FlameGraph repo\n<pre>% git clone https:\/\/github.com\/brendangregg\/FlameGraph fg<\/pre>\n<\/li>\n<li>Create Docker image\n<pre>Follow the instructions here: <a href=\"http:\/\/www.max-sperling.bplaced.net\/?p=18563\">C++ develop container (Docker)<\/a><\/pre>\n<\/li>\n<li>Run Docker container<\/strong>\n<pre>% docker run -it --rm -v $(pwd):\/workspace --privileged cpp-dev<\/pre>\n<\/li>\n<li>Setup container\n<pre>\r\n# apt update && apt install -y g++ linux-perf\r\n# echo -1 > \/proc\/sys\/kernel\/perf_event_paranoid\r\n<\/pre>\n<\/li>\n<\/ol>\n<hr>\n<h2>Initial version<\/h2>\n<pre class=\"brush: cpp; gutter: false; title: main.cpp; notranslate\" title=\"main.cpp\">\r\n#include &lt;iostream&gt;\r\n#include &lt;numeric&gt;\r\n#include &lt;random&gt;\r\n#include &lt;vector&gt;\r\n\r\nuint32_t calcAverage(const std::vector&lt;uint32_t&gt;&amp; data) {\r\n    if (data.empty()) return 0;\r\n    uint64_t sum = std::accumulate(data.begin(), data.end(), uint64_t(0));\r\n    return static_cast&lt;uint32_t&gt;(sum \/ data.size());\r\n}\r\n\r\nstd::vector&lt;uint32_t&gt; createRndData(uint64_t num) {\r\n    std::vector&lt;uint32_t&gt; data(num);\r\n    std::mt19937 gen(std::random_device{}());\r\n    std::uniform_int_distribution&lt;uint32_t&gt; dist(0, RAND_MAX);\r\n    for (uint64_t i = 0; i &lt; num; ++i) {\r\n        data[i] = dist(gen);\r\n    }\r\n    return data;\r\n}\r\n\r\nint main() {\r\n    uint64_t num = 100&#039;000&#039;000;\r\n    std::cout &lt;&lt; &quot;Average: &quot; &lt;&lt; calcAverage(createRndData(num)) &lt;&lt; std::endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<pre>\r\n# g++ main.cpp -g -o calc.out\r\n# perf record --freq 10000 --call-graph fp .\/calc.out\r\n# perf script | \/workspace\/fg\/stackcollapse-perf.pl | \/workspace\/fg\/flamegraph.pl > flamegraph_initial.svg\r\n<\/pre>\n<p><a href=\"http:\/\/www.max-sperling.bplaced.net\/wp-content\/uploads\/2025\/01\/flamegraph_initial.svg\"><img decoding=\"async\" src=\"http:\/\/www.max-sperling.bplaced.net\/wp-content\/uploads\/2025\/01\/flamegraph_initial.svg\" class=\"aligncenter\" \/><\/a><\/p>\n<p>The function createRndData takes 90% of the calculation time. Let&#8217;s try to reduce it.<\/p>\n<hr>\n<h2>Updated version<\/h2>\n<pre class=\"brush: cpp; gutter: false; title: main.cpp; notranslate\" title=\"main.cpp\">\r\n#include &lt;cstdlib&gt;\r\n#include &lt;ctime&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;numeric&gt;\r\n#include &lt;vector&gt;\r\n\r\nuint32_t calcAverage(const std::vector&lt;uint32_t&gt;&amp; data) {\r\n    if (data.empty()) return 0;\r\n    uint64_t sum = std::accumulate(data.begin(), data.end(), uint64_t(0));\r\n    return static_cast&lt;uint32_t&gt;(sum \/ data.size());\r\n}\r\n\r\nstd::vector&lt;uint32_t&gt; createRndData(uint64_t num) {\r\n    srand(time(NULL));\r\n    std::vector&lt;uint32_t&gt; data(num);\r\n    for (uint64_t i = 0; i &lt; num; ++i) {\r\n        data[i] = static_cast&lt;uint32_t&gt;(rand());\r\n    }\r\n    return data;\r\n}\r\n\r\nint main() {\r\n    uint64_t num = 100&#039;000&#039;000;\r\n    std::cout &lt;&lt; &quot;Average: &quot; &lt;&lt; calcAverage(createRndData(num)) &lt;&lt; std::endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<pre>\r\n# g++ main.cpp -g -o calc.out\r\n# perf record --freq 10000 --call-graph fp .\/calc.out\r\n# perf script | \/workspace\/fg\/stackcollapse-perf.pl | \/workspace\/fg\/flamegraph.pl > flamegraph_updated.svg\r\n<\/pre>\n<p><a href=\"http:\/\/www.max-sperling.bplaced.net\/wp-content\/uploads\/2025\/01\/flamegraph_updated.svg\"><img decoding=\"async\" src=\"http:\/\/www.max-sperling.bplaced.net\/wp-content\/uploads\/2025\/01\/flamegraph_updated.svg\" class=\"aligncenter\" \/><\/a><\/p>\n<p>Now, the function createRndData takes only 65% of the calculation time. Yeah. \ud83c\udf89<\/p>\n<hr>\n<h2>Disclaimer<\/h2>\n<p>It&#8217;s build without any optimization!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Setup Get FlameGraph repo % git clone https:\/\/github.com\/brendangregg\/FlameGraph fg Create Docker image Follow the instructions here: C++ develop container (Docker)<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false},"categories":[28,82],"tags":[],"_links":{"self":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/18216"}],"collection":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=18216"}],"version-history":[{"count":35,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/18216\/revisions"}],"predecessor-version":[{"id":18772,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/18216\/revisions\/18772"}],"wp:attachment":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=18216"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=18216"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=18216"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}