diff --git a/documentation/TraceEvent/TraceEventProgrammersGuide.md b/documentation/TraceEvent/TraceEventProgrammersGuide.md index 0fc9e794e..9885f17a8 100644 --- a/documentation/TraceEvent/TraceEventProgrammersGuide.md +++ b/documentation/TraceEvent/TraceEventProgrammersGuide.md @@ -935,4 +935,4 @@ Unfortunately when a provider registers with the operating system (the Win32 `Ev ## On the fly filtering AND Logging using `ETWReloggerTraceEventSource` -TODO +TODO \ No newline at end of file diff --git a/src/PerfView/SupportFiles/HtmlReportUsersGuide.htm b/src/PerfView/SupportFiles/HtmlReportUsersGuide.htm index 8cbad3c4e..57e0b5d20 100644 --- a/src/PerfView/SupportFiles/HtmlReportUsersGuide.htm +++ b/src/PerfView/SupportFiles/HtmlReportUsersGuide.htm @@ -251,8 +251,34 @@
+
+ EventPipe is a technology in .NET Core 3.1 on that allows the collection of events and CPU + sampling on all platforms. The CPU sampling performed by EventPipe is only aware of managed + code, which means that transitions into native code, e.g., P/Invokes, won't appear in the + trace. This means that stacks that containing native code will end with the last managed frame. +
++ For example, if an application has a sequence of methods Main->A->B->C->MyNativeFunction, + where MyNativeFunction P/Invokes into native code, then samples collected while that native + code is on the stack will only contain Main->A->B->C->MyNativeFunction. Any native functions + after the P/Invoke method won't appear in the trace. +
++ During a typical CPU usage investigation, you may want to ask about on-CPU vs off-CPU time to determine + when your code is blocked waiting or actively doing work. Due to the only knowing about + managed frames, CPU samples collected via EventPipe can't give exact on/off-CPU information. Instead, + the TraceEvent library uses a heuristic to add pseudo-frames to the trace that indicate whether there + are additional native frames on the stack or not. When a nettrace file is opened in the "Thread Time" + view or is exported to another format, e.g., SpeedScope, the heuristic will insert either UNMANAGED_CODE_TIME + or CPU_TIME onto the stacks. UNMANAGED_CODE_TIME represents stacks where there are one or more native + frames after the last managed frame and that these frames may be blocked waiting or actively on the CPU. + CPU_TIME represents stacks where the last managed frame is the function currently on the CPU and doing work. +
+