Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs on UNMANAGED_CODE_TIME and CPU_TIME #1613

Merged
merged 2 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion documentation/TraceEvent/TraceEventProgrammersGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
30 changes: 28 additions & 2 deletions src/PerfView/SupportFiles/HtmlReportUsersGuide.htm
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,34 @@ <h3>
TypeLoad information is only available in .NET 5 and above.

Otherwise, the data captured will be restricted to JIT and assembly load operations. The /RuntimeLoading switch may also be used.
<hr />
<p>&nbsp;</p>
<hr />
<h3>
<a id="UnderstandingEventPipeThreadTime">Understanding EventPipe Thread Time</a>
</h3>
<p>
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.
</p>
<p>
For example, if an application has a sequence of methods <tt>Main->A->B->C->MyNativeFunction</tt>,
where <tt>MyNativeFunction</tt> P/Invokes into native code, then samples collected while that native
code is on the stack will only contain <tt>Main->A->B->C->MyNativeFunction</tt>. Any native functions
after the P/Invoke method won't appear in the trace.
</p>
<p>
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 <tt>UNMANAGED_CODE_TIME</tt>
or <tt>CPU_TIME</tt> onto the stacks. <tt>UNMANAGED_CODE_TIME</tt> 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.
<tt>CPU_TIME</tt> represents stacks where the last managed frame is the function currently on the CPU and doing work.
</p>
<hr />
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
Expand Down