GCC Profiler Internals
trofi.github.io
trofi.github.io
2. Do not use instrumenting profilers for measuring code.
except when that is useful 8-)
I still think the weird limitations you get from "what about embedded" are often just obvious canaries for problems present throughout much of the vast diversity of computing. For example, sampling profilers used to have serious issues on WSL (where perf must still be manually compiled) and WINE. Having instrumentation hooks also makes things like AFL and custom sanitizers possible. The flexibility isn't always reasonable (e.g. don't assume little endian, don't assume 8-bit bytes), but there may be valid use cases that weren't considered at the toolchain/language level.
If you want to know the exact ratios of how hot code is, then yes instrumentation can be a godsend, however in my experience most people are simply mislead by them because a naive instrumenting profiler usually does not have enough information to capture the right context (i.e. the call stack).
For most applications profiling is basically just an exercise in proving your own mental model of execution correct, not fine-tuning (initially at least).
https://youtu.be/6TDZa5LUBzY I gave a talk on this in November.
As a example consider viztracer [1] for Python. By using a aggregate visualizer such as a flame graph you can figure out what is taking the most time then you can use a tracing visualizer to figure out the exact call stacks and system execution and state that caused it. Not only that, a tracing visualizer lets you diagnose whole system performance and makes it trivial to identify 1 in 1000 anomalous execution patterns (with a 4k screen a anomalous execution pattern stands out like a 4 pixel dead spot). In addition you also get vastly less biased information for parallel execution and get easy insights into parallel execution slowdowns, interference, contention, and blocking behaviors.
The only advantages highlighted in your video that still apply to a good instrumenting profiler are:
1. Multi-language support.
2. Performance counters (though that is solved by doing manual tracking after you know the hotspots and causes).
3. Overhead (if you are using low sampling frequency). Even then a good tracing instrumentation implementation should only incur low double-digit percent overhead and maybe 100% overhead in truly pathological cases involving only small functions where the majority of the execution time is literally spent in function call overhead.
4. No need for recompilation, but you are already looking to make performance changes and test so you already intend to rebuild frequently to test those experiments. In addition, the relative difference in information is so humongous that this is not even worth contemplating unless it is a hard requirement like evaluating something in the field.
I stopped using it a long time ago since it was so slow and not thread-safe. But I occasionally miss the comprehensive coverage it had. If the situation has changed, I'd love to give it another shot.