Ferramentas de diagnóstico em paralelo (Runtime de Simultaneidade)
O Visual Studio fornece amplo suporte para depuração e criação de perfil de aplicativos multi-threaded.
Depuração
O depurador do Visual Studio inclui a janela Pilhas Paralelas, a janela Tarefas Paralelas e a janela Relógio Paralelo. Para mais informações, confira Guia passo a passo: Como depurar um aplicativo paralelo e Como usar a janela de inspeção paralela.
Criação de perfil
As ferramentas de criação de perfil fornecem três exibições de dados que exibem informações gráficas, tabulares e numéricas sobre como um aplicativo com multi-thread interage consigo mesmo e com outros programas. Os modos de exibição permitem identificar rapidamente áreas de interesse e navegar de pontos nas exibições gráficas para pilhas de chamadas, sites de chamadas e código-fonte. Para saber mais, confira Visualização Simultânea.
Rastreamento de eventos
O Runtime de Simultaneidade usa o ETW (Rastreamento de Eventos para Windows) para notificar ferramentas de instrumentação, como criadores de perfil, quando ocorrem vários eventos. Esses eventos incluem quando um agendador é ativado ou desativado, quando um contexto começa, termina, bloqueia, desbloqueia ou produz e quando um algoritmo paralelo começa ou termina.
Ferramentas como a Visualizador de Simultaneidade utilizam essa funcionalidade; portanto, normalmente você não precisa trabalhar diretamente com esses eventos. No entanto, esses eventos são úteis quando você está desenvolvendo um criador de perfil personalizado ou quando você usa ferramentas de rastreamento de eventos, como o Windows Performance Toolkit.
O Runtime de Simultaneidade gera esses eventos somente quando o rastreamento está habilitado. Chame a função concurrency::EnableTracing para habilitar o rastreamento de eventos e a função concurrency::DisableTracing para desabilitar o rastreamento.
A tabela a seguir descreve os eventos que o runtime gera quando o rastreamento de eventos está habilitado:
Evento | Descrição | Valor |
---|---|---|
concurrency::ConcRT_ProviderGuid | O identificador do provedor ETW para o Runtime de Simultaneidade. | f7b697a3-4db5-4d3b-be71-c4d284e6592f |
concurrency::ContextEventGuid | Marca eventos relacionados a contextos. | 5727a00f-50be-4519-8256-f7699871fecb |
concurrency::PPLParallelForEventGuid | Marca a entrada e a saída para chamadas para o algoritmo concurrency::parallel_for. | 31c8da6b-6165-4042-8b92-949e315f4d84 |
concurrency::PPLParallelForeachEventGuid | Marca a entrada e a saída para chamadas para o algoritmo concurrency::parallel_for_each. | 5cb7d785-9d66-465d-bae1-4611061b5434 |
concurrency::PPLParallelInvokeEventGuid | Marca a entrada e a saída para chamadas para o algoritmo concurrency::parallel_invoke. | d1b5b133-ec3d-49f4-98a3-464d1a9e4682 |
concurrency::SchedulerEventGuid | Marca eventos relacionados ao Agendador de Tarefas. | e2091f8a-1e0a-4731-84a2-0dd57c8a5261 |
concurrency::VirtualProcessorEventGuid | Marca eventos relacionados a processadores virtuais. | 2f27805f-1676-4ecc-96fa-7eb09d44302f |
O Runtime de Simultaneidade define, mas atualmente não gera, os eventos a seguir. O runtime reserva estes eventos para uso futuro:
A enumeração concurrency::ConcRT_EventType especifica as possíveis operações que um evento rastreia. Por exemplo, na entrada do algoritmo parallel_for
, o runtime gera o evento PPLParallelForEventGuid
e fornece CONCRT_EVENT_START
como a operação. Antes que o algoritmo parallel_for
retorne, o runtime aciona novamente o evento PPLParallelForEventGuid
e fornece CONCRT_EVENT_END
como a operação.
O exemplo a seguir ilustra como habilitar o rastreamento de uma chamada para parallel_for
. O runtime não rastreia a primeira chamada para parallel_for
porque o rastreamento não está habilitado. A chamada para EnableTracing
permite que o runtime rastreie a segunda chamada para 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();
}
O runtime rastreia o número de vezes que você chama EnableTracing
e DisableTracing
. Portanto, se você chamar EnableTracing
várias vezes, deverá chamar DisableTracing
o mesmo número de vezes para desabilitar o rastreamento.