Parallel Diagnostic Tools (Concurrency Runtime)
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
Visual Studio provides extensive support for debugging and profiling multi-threaded applications.
Debugging
The Visual Studio debugger includes the Parallel Stacks window, Parallel Tasks window, and Parallel Watch window. For more information, see Walkthrough: Debugging a Parallel Application and How to: Use the Parallel Watch Window.
Profiling
The profiling tools provide three data views that display graphical, tabular and numerical information about how a multi-threaded application interacts with itself and with other programs. The views enable you to quickly identify areas of concern, and to navigate from points on the graphical displays to call stacks, call sites, and source code. For more information, see Concurrency Visualizer.
Event Tracing
The Concurrency Runtime uses Event Tracing for Windows (ETW) to notify instrumentation tools, such as profilers, when various events occur. These events include when a scheduler is activated or deactivated, when a context begins, ends, blocks, unblocks, or yields, and when a parallel algorithm begins or ends.
Tools such as the Concurrency Visualizer utilize this functionality; therefore, you typically do not have to work with these events directly. However, these events are useful when you are developing a custom profiler or when you use event tracing tools such as Xperf.
The Concurrency Runtime raises these events only when tracing is enabled. Call the concurrency::EnableTracing function to enable event tracing and the concurrency::DisableTracing function to disable tracing.
The following table describes the events that the runtime raises when event tracing is enabled:
Event | Description | Value |
---|---|---|
concurrency::ConcRT_ProviderGuid | The ETW provider identifier for the Concurrency Runtime. | f7b697a3-4db5-4d3b-be71-c4d284e6592f |
concurrency::ContextEventGuid | Marks events that are related to contexts. | 5727a00f-50be-4519-8256-f7699871fecb |
concurrency::PPLParallelForEventGuid | Marks the entrance and exit to calls to the concurrency::parallel_for algorithm. | 31c8da6b-6165-4042-8b92-949e315f4d84 |
concurrency::PPLParallelForeachEventGuid | Marks the entrance and exit to calls to the concurrency::parallel_for_each algorithm. | 5cb7d785-9d66-465d-bae1-4611061b5434 |
concurrency::PPLParallelInvokeEventGuid | Marks the entrance and exit to calls to the concurrency::parallel_invoke algorithm. | d1b5b133-ec3d-49f4-98a3-464d1a9e4682 |
concurrency::SchedulerEventGuid | Marks events that are related to the Task Scheduler. | e2091f8a-1e0a-4731-84a2-0dd57c8a5261 |
concurrency::VirtualProcessorEventGuid | Marks events that are related to virtual processors. | 2f27805f-1676-4ecc-96fa-7eb09d44302f |
The Concurrency Runtime defines, but does not currently raise, the following events. The runtime reserves these events for future use:
The concurrency::ConcRT_EventType enumeration specifies the possible operations that an event tracks. For example, at the entrance of the parallel_for
algorithm, the runtime raises the PPLParallelForEventGuid
event and provides CONCRT_EVENT_START
as the operation. Before the parallel_for
algorithm returns, the runtime again raises the PPLParallelForEventGuid
event and provides CONCRT_EVENT_END
as the operation.
The following example illustrates how to enable tracing for a call to parallel_for
. The runtime does not trace the first call to parallel_for
because tracing it not enabled. The call to EnableTracing
enables the runtime to trace the second call to parallel_for
.
// etw.cpp
// compile with: /EHsc
#include <ppl.h>
using namespace concurrency;
int wmain()
{
// Perform some parallel work.
// Event tracing is disabled at this point.
parallel_for(0, 10000, [](int i) {
// TODO: Perform work.
});
// Enable tracing for a second call to parallel_for.
EnableTracing();
parallel_for(0, 10000, [](int i) {
// TODO: Perform work.
});
DisableTracing();
}
The runtime tracks the number of times that you call EnableTracing
and DisableTracing
. Therefore, if you call EnableTracing
multiple times, you must call DisableTracing
the same number of times in order to disable tracing.