Critical path analysis in Timing Captures

Critical path analysis helps you understand why a selected PIX event took as long as it did. PIX uses the CPU context switch data in a Timing Capture to compute the critical path for the event: the series of events and thread dependencies that, if shortened, would reduce the overall duration of the selected event. The critical path includes the running threads, readying relationships, and CPU-core contention that contribute to the event's duration.

Use this analysis when a PIX event includes a long stall or other unscheduled interval. For example, a MainLoop event that represents one frame of CPU work might show execution on its thread at the start and end of the frame, with a long cross-hatched stretch in the middle where the thread isn't running. If you shorten work on the critical path, or remove contention that keeps the selected thread from running, you can reduce or eliminate that stall and reduce the duration of the selected event.

Calculate a critical path

  1. Open a Timing Capture in the Timeline layout.
  2. Select one PIX event in a CPU thread or core lane.
  3. Right-click the selected event, and then select Calculate critical path for selected PIX event.

PIX analyzes the selected event's time range in the background. If analysis succeeds, PIX adds a lane named Critical Path: followed by the event name near the top of the Timeline and scrolls to it.

Note

PIX enables the command only when exactly one PIX event is selected. If PIX can't calculate a path for the selected event, it leaves the Timeline unchanged.

Read the critical path lane

The critical path lane shows the CPU work that contributes to the selected event's duration. The first and last blocks are usually work from the selected event's thread. Blocks between them are other threads that ran while the selected thread was stalled or waiting to resume, so the stall that appears as unscheduled time on the regular thread lane is filled in with the events that account for the stalled time.

The colored strip in the lane changes color when the critical path moves to a different thread. PIX uses the thread lane colors, so the colors match the corresponding CPU thread lanes. For example, if the strip changes color three times during a stall, three different threads ran on the critical path during that time.

Vertical red boundaries mark transitions between critical path blocks. These boundaries usually correspond to context switches or readying events. Select a boundary to select the related context switch or readying event in the Timeline. When readying data is available, PIX draws a dependency arrow between the two threads, which indicates a direct dependency between them.

The critical path lane can also show PIX events and CPU samples from the threads that appear on the path. Use the lane configuration controls to show or hide the same kinds of data you use on other CPU lanes, such as PIX events, context switches, samples, labels, and flattening.

Understand why a block is on the path

Hover over a block or transition in the critical path lane to see the thread name, CPU core, and thread priority for that block. PIX adds a reason when it can identify one:

  • The tooltip phrase readied by, followed by a thread name, means the block started because another thread made it ready to run.
  • The tooltip phrase Core, followed by a core number and contention, means the block delayed a readied thread by running on the same core.

Blocks from two threads can appear one after another on the critical path even when neither thread depends on the other. Because they run in sequence rather than in parallel, they lengthen the stall. Check the tooltips for these blocks: if both threads ran on the same core, and the thread that ran first had the same or higher priority, core contention serialized them. One way to fix this is to assign the threads to different CPU cores.

Use these reasons to decide what to inspect next. For example, if the selected event is stalled because a loader thread readied worker threads, inspect the loader and worker work on the path. If two worker threads serialize because they contend for the same core, investigate affinity, priority, or scheduling decisions that prevent them from running in parallel.

Example: diagnose a stalled frame

Suppose the critical path for a MainLoop event on the AppMain thread shows a long stall filled in by work from three other threads. Inspecting the transitions and tooltips reveals the following chain:

  1. Selecting the red boundary where AppMain stops running draws a dependency arrow to a Loader thread. The tooltip for the Loader block shows that it was readied by AppMain. This dependency caused AppMain to stop running.
  2. Selecting the next transitions shows that Loader readied two more threads, WorkerH1 and Worker.
  3. WorkerH1 and Worker don't depend on each other, but their blocks run one after another. Their tooltips show that both threads ran on Core 4 with the same priority, so core contention kept them from running in parallel and further lengthened the stall.
  4. AppMain had to wait for WorkerH1 and Worker to finish before it resumed execution.

To shorten this frame, you could reduce the work that AppMain waits on, or assign WorkerH1 and Worker to different cores so that they can run in parallel.

Inspect the selected transition

When you select a critical path boundary, use Element Details to inspect the selected context switch or readying event. For readying events, Element Details shows the readying thread, the readied thread, the ready time, and the call stacks when they are available.

You can also compare the critical path lane with the regular thread and core lanes. The regular lanes show the surrounding execution, while the critical path lane filters that execution to the work most relevant to the selected PIX event's duration.