Description
Background
Currently, all events emitted from the managed space by EventSource
will do a stackwalk, see eventpipeinternal.cpp:121. The obligatory stackwalk leads to significant performance penalty for frequent events while in some cases the stacktrace is not required.
As an example, I'm working on the association between CPU samples from perf record
and spans of System.Diagnostics.Activity
. The idea is to bring the profiling data on the application level, showing the cpu usage grouped by activity name. To make it work, I record all the activities with Microsoft-Diagnostics-DiagnosticSource
and track TraceSyncrhonousWorkStart
and TraceOperationStart
events from System.Threading.Tasks.TplEventSource
to follow the asynchronous flow.
With the stacktraces, the idea is not viable because the application spends more than half of the cpu time doing stackwalks. By disabling the stacktrace recording (just put false
in the file linked above), the overhead drops down to around 3% showing really promising results.
Proposed Feature
I propose to introduce the bool collectStacks
parameter when creating an EventPipe session. The change is required both in the runtime implementation and the DiagnosticsClient
. For managed events the effect of session.collectStacks
would be straightforward as there's no way to control it in EventSource definition. For the native we could check session.collectStacks && event.needStack
to respect ClrEtwAllMeta.lst
Why I think introducing this parameter on the session level is a good idea:
- For the same event, the importance of the stacktrace depends on the usecase. Thus the user should be able to choose
- It seems too complex for me to propagate the flag per provider, even more complex per keyword or per event. On the other hand disabling the stacks with the environment variable (per process) will severely limit other usecases.
- If we need the events both with and without the stack at the same time, we could start 2 parallel sessions. Not very convenient but not too much trouble either.
- It's relatively easy to support backward compatibility as we don't change the defaults and the parameter could be optional
Usage Examples
Starting the session:
var session = client.StartEventPipeSession(providers, collectStacks = false);