<div dir="ltr">I recently opened <a href="https://gitlab.freedesktop.org/mesa/mesa/-/issues/4262" target="_blank">issue 4262</a> to begin the discussion on integrating perfetto into mesa.<div><br></div><div><b>Background</b></div><div><br></div><div>System-wide tracing is an invaluable tool for developers to find and fix performance problems. The perfetto project enables a combined view of trace data from kernel ftrace, GPU driver and various manually-instrumented tracepoints throughout the application and system. This helps developers quickly answer questions like:</div><div><ul><li>How long are frames taking?</li><li>What caused a particular frame drop?</li><li>Is it CPU bound or GPU bound?<br></li><li>Did a CPU core frequency drop cause something to go slower than usual?</li><li>Is something else running that is stealing CPU or GPU time? Could I fix that with better thread/context priorities?</li><li>Are all CPU cores being used effectively? Do I need sched_setaffinity to keep my thread on a big or little core?<br></li><li>What’s the latency between CPU frame submit and GPU start?</li></ul></div><div><b>What Does Mesa + Perfetto Provide?</b></div><div><br></div><div>Mesa is in a unique position to produce GPU trace data for several GPU vendors without requiring the developer to build and install additional tools like <a href="https://gitlab.freedesktop.org/Fahien/gfx-pps" target="_blank">gfx-pps</a>.</div><div><br></div><div></div><div>The key is making it easy for developers to use. Ideally, perfetto is eventually available by default in mesa so that if your system has perfetto traced running, you just need to run perfetto (perhaps along with setting an environment variable) with the mesa categories to see:</div><div><ul><li>GPU processing timeline events.</li><li>GPU counters.</li><li>CPU events for potentially slow functions in mesa like shader compiles.</li></ul><div>Example of what this data might look like (with fake GPU events):</div></div><img src="cid:ii_kl1me01m1" alt="percetto-gpu-example.png" width="562" height="157"><br><div><br></div><div><b>Runtime Characteristics</b><br></div><div><ul><li>~500KB additional binary size. Even with using only the basic features of perfetto, it will increase the binary size of mesa by about 500KB.</li><li>Background thread. Perfetto uses a background thread for communication with the system tracing daemon (traced) to advertise trace data and get notification of trace start/stop.<br></li><li>Runtime overhead when disabled is designed to be optimal with one predicted branch, typically <a href="https://perfetto.dev/docs/instrumentation/track-events#performance" target="_blank">a few CPU cycles</a> per event. While enabled, the overhead can be around 1 us per event.<br></li></ul></div><div><b>Integration Challenges</b></div><div><ul><li>The perfetto SDK is C++ and designed around macros, lambdas, inline templates, etc. There are ongoing discussions on providing an official perfetto C API, but it is not yet clear when this will land on the perfetto roadmap.</li><li>The perfetto SDK is an amalgamated .h and .cc that adds up to 100K lines of code.</li><li>Anything that includes perfetto.h takes a long time to compile.</li><li>The current Perfetto SDK design is incompatible with being a shared library behind a C API.</li></ul></div><div><div></div></div><div><b>Percetto</b><br></div><div><br></div><div>The <a href="https://github.com/olvaffe/percetto" target="_blank">percetto library</a> was recently implemented to provide an interim C API for perfetto. It provides efficient support for scoped trace events, multiple categories, counters, custom timestamps, and debug data annotations. Percetto also provides some features that are important to mesa, but not available yet with perfetto SDK:</div><div><ul><li>Trace events from multiple perfetto instances in separate shared libraries (like mesa and virglrenderer) show correctly in a single process and thread view.</li><li>Counter tracks and macro API.</li></ul></div><div>Percetto is missing API for perfetto's GPU DataSource and counter support, but that feature could be implemented next if it is important for mesa. With the existing percetto API mesa could present GPU trace data as named 'slice' events and int64_t counters with custom timestamps as shown in the image above (based on <a href="https://github.com/olvaffe/percetto/blob/main/examples/timestamps.c">this sample</a>).</div><div><br></div><div><b>Mesa Integration Alternatives</b><br></div><div><br></div><div>Note: we have some pressing needs for performance analysis in Chrome OS, so I'm intentionally leaving out the alternative of waiting for an official perfetto C API. Of course, once that C API is available it would become an option to migrate to it from any of the alternatives below.</div><div><br></div><div>Ordered by difficulty with easiest first:</div><div><ol><li>Statically link with percetto as an optional external dependency (<a href="https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/480" target="_blank">virglrenderer now has this approach</a>).<br></li><ul><li>Pros: API already supports most common tracing needs. Tested and used by an increasing number of CrOS components.</li><li>Cons: External dependency for optional mesa build option.</li></ul><li>Embed Perfetto SDK + a Percetto fork/copy.</li><ul><li>Pros: API already supports most common tracing needs. No added external dependency for mesa.</li><li>Cons: Percetto code divergence, bug fixes need to land in two trees.</li></ul><li>Embed Perfetto SDK + custom C wrapper.</li><ul><li>Pros: Tailored API for mesa's needs.</li><li>Cons: Nontrivial development efforts and maintenance.</li></ul><li>Generate C stubs for the Perfetto protobuf and reimplement the Perfetto SDK in C.</li><ul><li>Pros: Tailored API for mesa's needs. Possible smaller binary impact from simpler implementation.</li><li>Cons: Significant development efforts and maintenance.</li></ul></ol><div>Regardless of the integration direction, I expect we would disable perfetto in the default build for now to minimize disruption.</div><div><br></div><div>I like #1, because there are some nontrivial subtleties to the C wrapper that provide both API conveniences and runtime performance that would need to be reimplemented or maintained with the other options. I will also volunteer to do #1 or #2, but I'm not sure I have time for #3 or #4 :D.</div></div><div><br></div><div>Any other thoughts on how best to integrate perfetto into mesa?</div><div><br></div><div>-jb</div><div></div></div>