-
Notifications
You must be signed in to change notification settings - Fork 387
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);