Partilhar via


Visualização de encadeamentos no Visualizador de Concorrência

O modo de exibição Threads é o modo de exibição mais detalhado e rico em recursos no Visualizador de Simultaneidade. Na visualização Threads , você pode identificar quais threads estão executando código durante um segmento de execução e analisar se os threads estão sendo executados ou bloqueados devido à sincronização, E/S ou outros motivos. Threads exibem relatórios, também elaboram o perfil da execução da árvore de pilha de chamadas e desbloqueiam threads.

Enquanto os threads estão em execução, o Visualizador de Simultaneidade coleta amostras. Quando um thread parou de ser executado, o visualizador examina todos os eventos de alternância de contexto do sistema operacional para o thread. As mudanças de contexto podem ocorrer porque:

  • Uma thread está bloqueada numa primitiva de sincronização.
  • O quantum de um thread expira.
  • Uma thread faz uma solicitação de entrada/saída de bloqueio.

O Visualizador de Simultaneidade categoriza eventos de threads e de comutação de contexto e pesquisa nas pilhas de chamadas das threads para encontrar APIs de bloqueio conhecidas. Ele exibe as categorias de thread na legenda ativa no canto inferior esquerdo na visualização Threads . Na maioria dos casos, você pode identificar a causa raiz de um evento de bloqueio examinando as pilhas de chamadas que correspondem a eventos de alternância de contexto.

Caso não haja correspondência da pilha de chamadas, o Visualizador de Simultaneidade usará o motivo de espera fornecido pelo Windows. No entanto, a categoria Windows pode ser baseada em um detalhe de implementação e pode não refletir a intenção do usuário. Por exemplo, o Windows relata o motivo da espera para o bloqueio em um bloqueio de leitor-gravador fino nativo como E/S em vez de Sincronização.

A vista Threads também mostra dependências entre threads. Por exemplo, se você identificar um thread bloqueado em um objeto de sincronização, poderá encontrar o thread que o desbloqueou. Você pode examinar a pilha de chamadas para o thread de desbloqueio no ponto em que ele desbloqueou o outro.

Você pode usar o modo de exibição Threads para:

  • Identifique os motivos pelos quais a interface do usuário (UI) de um aplicativo não responde durante determinadas fases de execução.
  • Determine a quantidade de tempo gasto em bloqueios de sincronização, entrada/saída, falhas de página e outros eventos.
  • Descubra o grau de interferência de outros processos que estão sendo executados no sistema.
  • Identificar problemas de balanceamento de carga para execução paralela.
  • Encontre as razões para uma escalabilidade subótima ou inexistente. Por exemplo, por que o desempenho de um aplicativo paralelo não melhora quando mais núcleos lógicos estão disponíveis?
  • Entenda o grau de simultaneidade no aplicativo, para ajudar na paralelização.
  • Identifique dependências entre threads de trabalho e caminhos críticos de execução.

Usar o modo de exibição Threads

Para iniciar o Visualizador de Simultaneidade, selecione Analisar>Visualizador de Simultaneidade e selecione uma opção, como Iniciar Novo Processo.

O Visualizador de Simultaneidade inicia o aplicativo e coleta um rastreamento até que você selecione Parar Coleta. Em seguida, o visualizador analisa o rastreamento e exibe os resultados na página do relatório de rastreamento.

Selecione a guia Threads no canto superior esquerdo do relatório para abrir a visualização Threads .

Visualização de Tópicos

Selecione intervalos de tempo e threads para iniciar uma análise de desempenho.

Análise da linha do tempo

A parte superior da vista Threads é uma linha do tempo. A linha do tempo mostra a atividade de todos os threads no processo e todos os dispositivos de disco físico no computador host. Ele também exibe a atividade da GPU e eventos de marcador.

Na linha do tempo, o eixo x é o tempo, e no eixo y estão vários canais:

  • Dois canais de E/S para cada unidade de disco no sistema, um canal para leituras e outro para gravações.
  • Um canal para cada thread no processo.
  • Canais de marcador, se houver eventos de marcador no rastreamento. Os canais de marcação aparecem inicialmente sob os canais de thread que geraram esses eventos.
  • Canais GPU.

Inicialmente, os threads são classificados na ordem em que são criados, portanto, o thread principal do aplicativo é o primeiro. Selecione outra opção na lista suspensa Classificar por para classificar threads por outro critério, por exemplo Execução.

As cores da linha do tempo indicam o estado de um thread em um determinado momento. Os segmentos verdes estão em execução, os segmentos vermelhos são bloqueados para sincronização, os segmentos amarelos são preemptivos e os segmentos roxos estão envolvidos em operações de E/S do dispositivo.

Você pode aumentar o zoom para ver mais detalhes ou reduzir para exibir um intervalo de tempo maior. Selecione segmentos e pontos no gráfico para obter detalhes sobre categorias, horários de início, atrasos e estados da pilha de chamadas.

Use a linha do tempo para examinar o equilíbrio de trabalho entre threads envolvidos em um loop paralelo ou em tarefas simultâneas. Se um thread está demorando mais para ser concluído do que os outros, o trabalho pode estar desequilibrado. Você pode melhorar o desempenho do seu aplicativo distribuindo o trabalho de forma mais uniforme entre os threads.

Se apenas um thread estiver sendo executado em um determinado momento, o aplicativo pode não estar aproveitando ao máximo a simultaneidade no sistema. Pode usar o gráfico temporal para examinar as dependências entre threads, bem como as relações temporais entre threads que bloqueiam e threads bloqueados. Para reorganizar threads, selecione um thread e, em seguida, selecione o ícone para cima ou para baixo na barra de ferramentas.

Você pode ocultar threads que não estão fazendo trabalho ou estão completamente bloqueados, porque suas estatísticas são irrelevantes e podem obstruir os relatórios. Oculte threads selecionando seus nomes e, em seguida, selecionando os ícones Ocultar threads selecionados ou Ocultar todos, exceto threads selecionados na barra de ferramentas. Para identificar threads a serem ocultados, selecione o link Resumo por thread no canto inferior esquerdo. Você pode ocultar os threads que não têm atividade no gráfico Resumo por thread .

Detalhes de execução do thread

Para obter informações mais detalhadas sobre um segmento de execução, selecione um ponto em um segmento verde da linha do tempo. O Visualizador de Simultaneidade exibe um cursor preto acima do ponto selecionado e mostra sua pilha de chamadas na guia Atual do painel inferior. Você pode selecionar vários pontos no segmento de execução.

Observação

O Visualizador de Simultaneidade pode não ser capaz de resolver uma seleção em um segmento de execução se a duração do segmento for inferior a um milissegundo.

Para obter um perfil de execução para todos os threads não ocultos no intervalo de tempo selecionado no momento, selecione Execução na legenda no canto inferior esquerdo.

Detalhes de bloqueio de tópicos

Para obter informações sobre uma região específica em um thread, passe o mouse sobre essa região na linha do tempo para exibir uma dica de ferramenta. A dica de ferramenta tem informações como categoria, hora de início e atraso. Selecione a região para exibir a pilha de chamadas nesse momento na guia Atual do painel inferior. O painel também mostra categoria, atraso, bloqueio de API, se houver, e desbloqueio de thread, se houver. Ao examinar a pilha de chamadas, você pode determinar os motivos subjacentes para eventos de bloqueio de threads.

Um caminho de execução pode ter vários eventos de bloqueio. Para examiná-los por categoria de bloqueio e encontrar áreas problemáticas mais rapidamente, selecione uma categoria de bloqueio na legenda à esquerda.

Dependências entre threads

O Visualizador de Simultaneidade mostra dependências entre threads, para que você possa determinar o que um thread bloqueado estava tentando fazer e qual outro thread permitiu que ele executasse.

Para determinar qual thread desbloqueou outro thread, selecione o segmento de bloqueio na linha do tempo. Se o Visualizador de Simultaneidade puder determinar o thread de desbloqueio, ele traçará uma linha entre o thread de desbloqueio e o segmento de execução que segue o segmento de bloqueio. Selecione a guia Pilha de desbloqueio no painel inferior para ver a pilha de chamadas relevante.

Relatórios de perfil

Abaixo do gráfico da linha do tempo, há um painel com as guias Relatório de Perfil, Atual e Stack de Desbloqueio. Os relatórios são atualizados automaticamente à medida que você altera a linha do tempo e as seleções de threads. Para rastros grandes, o painel de relatórios pode estar temporariamente indisponível durante o cálculo das atualizações.

Aba Relatório de Perfil

O Relatório de Perfil tem dois filtros:

  • Para filtrar entradas da árvore de chamadas em que pouco tempo foi gasto, digite um valor de filtro entre 0 e 99% no campo Redução de ruído em . O valor padrão é 2%.
  • Para exibir árvores de chamadas apenas para seu código, marque a caixa de seleção Apenas Meu Código . Para exibir todas as árvores de chamadas, desmarque a caixa de seleção.

A guia Relatório de Perfil mostra relatórios para as categorias e links na legenda. Para exibir um relatório, selecione uma das entradas à esquerda:

  • Execução O relatório de execução mostra o detalhamento do tempo que o aplicativo gastou na execução.

    Para localizar a linha de código na qual o tempo de execução é gasto, expanda a árvore de chamadas e, no menu de atalho para a entrada da árvore de chamadas, selecione Exibir origem ou Exibir sites de chamadas. View Source localiza a linha de código executada. Exibir Sites de Chamada localiza a linha de código que chamou a linha executada. Se existir apenas uma linha de chamada, o seu código será destacado. Se existirem vários sites de chamada, selecione o que pretende na caixa de diálogo e, em seguida, selecione Ir para a origem. Muitas vezes, é mais útil localizar o ponto de chamada que tem o maior número de instâncias, o maior tempo, ou ambos. Para obter mais informações, consulte Relatório de perfil de execução.

  • Sincronização O relatório de sincronização mostra as chamadas responsáveis pelos blocos de sincronização, juntamente com os tempos totais de bloqueio de cada pilha de chamadas. Para obter mais informações, consulte Tempo de sincronização.

  • E/S O relatório de E/S mostra as chamadas responsáveis pelos blocos de E/S, juntamente com os tempos totais de bloqueio de cada pilha de chamadas. Para obter mais informações, consulte Tempo de E/S (vista de Threads).

  • Suspensão O relatório Suspensão mostra as chamadas responsáveis pelos bloqueios de suspensão, juntamente com o tempo total de bloqueio de cada pilha de chamadas. Para obter mais informações, consulte Tempo de suspensão.

  • Gerenciamento de memória O relatório Gerenciamento de memória mostra as chamadas onde ocorreram bloqueios de gerenciamento de memória, juntamente com os tempos totais de bloqueio de cada pilha de chamadas. Use essas informações para identificar áreas com problemas excessivos de paginação ou coleta de lixo. Para obter mais informações, consulte Tempo de gerenciamento de memória.

  • Preempção O relatório de Preempção mostra onde os processos no sistema preemptaram o processo atual e os threads individuais que substituíram threads no processo atual. Você pode usar essas informações para identificar os processos e threads que são mais responsáveis pela preempção. Para obter mais informações, consulte Tempo de preempção.

  • Processamento da interface do usuário O relatório Processamento da interface do usuário mostra as chamadas responsáveis pelos blocos de processamento da interface do usuário, juntamente com os tempos totais de bloqueio de cada pilha de chamadas. Para obter mais informações, consulte Tempo de processamento da interface do usuário.

  • Resumo por thread Selecione Resumo por thread para exibir um gráfico mostrando o estado dos threads para o intervalo de tempo selecionado no momento. As colunas codificadas por cores mostram o tempo total que cada thread passou em execução, bloqueado, E/S e outros estados. Os fios são rotulados na parte inferior. Quando você ajusta o nível de zoom no gráfico da linha do tempo, esse gráfico é atualizado automaticamente.

    Em alguns níveis de zoom, alguns threads podem não aparecer no gráfico. Quando isso acontece, as elipses (...) aparecem à direita. Se o thread desejado não aparecer, você poderá ocultar outros threads. Para obter mais informações, consulte Relatório de resumo por tópico.

  • Operações de disco Selecione Operações de disco para mostrar os processos e threads envolvidos na E/S de disco para o processo atual, os arquivos que eles tocaram (por exemplo, DLLs que carregaram), quantos bytes leram e outras informações. Você pode usar esse relatório para avaliar o tempo gasto acessando arquivos durante a execução, especialmente quando o processo parece estar vinculado a E/S. Para obter mais informações, consulte Relatório de operações de disco.

Guia Atual

Esta aba mostra a pilha de chamadas para um ponto selecionado num segmento de execução no gráfico da linha do tempo. As pilhas de chamadas são cortadas para mostrar apenas a atividade relacionada ao seu aplicativo.

Guia Pilha de desbloqueio

Esta guia mostra qual thread desbloqueou o thread selecionado e a pilha de chamadas de desbloqueio.

Canais (visualização de threads)

O Visualizador de Simultaneidade mostra quatro tipos de canais: canais de thread, canais de disco, canais de marcador e canais de GPU.

Canais de thread

Um canal de thread mostra o estado do thread, por cor, para apenas um thread. Ao passar o cursor sobre o nome do canal, a função de arranque para o thread específico é exibida. O Visualizador de Simultaneidade deteta vários tipos de threads. Os tipos mais comuns são mostrados na tabela a seguir.

Thread Description
Tópico principal O thread que iniciou o aplicativo.
Thread de Trabalhador Um thread que foi criado pelo thread principal do aplicativo.
Thread de trabalho CLR Um thread de trabalho que foi criado pelo Common Language Runtime (CLR).
Assistente do Depurador Um thread de trabalho que foi criado pelo depurador do Visual Studio.
ConcRT Thread Um thread que foi criado pelo Microsoft Concurrency Runtime.
GDI Thread Um thread que foi criado pelo GDIPlus.
OLE/RPC Thread Um thread que foi criado como um thread de trabalho RPC.
RPC Thread Um thread que foi criado como um thread RPC.
Winsock Thread Um thread que foi criado como um Winsock Thread.
Pool de threads Um thread que foi criado pelo pool de threads CLR.

Canais de disco

Os canais de disco correspondem a unidades físicas no computador. Como existem canais separados para operações de leitura e gravação para cada unidade física no sistema, cada unidade tem dois canais. Os números de disco correspondem aos nomes de dispositivos do kernel. Um canal de disco é mostrado somente se houver atividade no disco.

Canais de marcação

Os canais de marcação correspondem a eventos gerados pelo aplicativo e pelas bibliotecas que ele usa. Por exemplo, a Biblioteca Paralela de Tarefas, a Biblioteca de Padrões Paralelos e o AMP C++ geram eventos que são exibidos como marcadores. Cada canal de marcador está associado a um ID de thread, que é exibido ao lado da descrição do canal. O ID identifica o thread que gerou o evento. A descrição do canal inclui o nome do provedor de Rastreamento de Eventos para Windows (ETW) que gerou os eventos. Se o canal exibir eventos do SDK do Visualizador de Simultaneidade, o nome da série também é exibido.

Canais GPU

Os canais GPU exibem informações sobre a atividade do DirectX 11 no sistema. Cada mecanismo DirectX associado à placa gráfica tem um canal separado. Os segmentos individuais representam o tempo gasto no processamento de um pacote DMA.

Copiar seleção

Para copiar toda a pilha de chamadas da guia relatório, clique em Copiar. Em seguida, você pode colar a pilha de chamadas em qualquer programa que ofereça suporte a essa ação.

Guia Atual

Ao clicar na guia Atual , você pode ver uma pilha de chamadas (se disponível) mais próxima do ponto de seleção atual na linha do tempo se um segmento de thread da CPU estiver selecionado. Nesse caso, o ponto de seleção é representado por uma seta preta, ou acento circunflexo, acima da linha do tempo. Quando um segmento de bloqueio é selecionado, o cursor não é exibido porque não houve execução. No entanto, o segmento ainda está destacado e uma sequência de chamadas é mostrada.

A guia Atual também exibe informações sobre segmentos de atividade do DirectX, marcadores e acesso de E/S. Para segmentos de atividade DirectX, são exibidas informações sobre a maneira como os pacotes DMA são processados pela fila de hardware. Para marcadores, são exibidas informações sobre a descrição e o tipo de marcador. Para acesso de E/S, são exibidas informações sobre o arquivo e o número de bytes lidos ou gravados.

Segmento de linha cronológica vazio

No Visualizador de Simultaneidade, o motivo pelo qual uma seção da linha do tempo está vazia (tem um fundo branco) depende do tipo de canal.

  • Para um canal de encadeamento da CPU, isso significa que o encadeamento não existia durante esta parte da linha temporal. Se você estiver interessado no thread, você pode encontrar sua seção de execução usando o controle de zoom ou rolando horizontalmente.

  • Para um canal de E/S, isso significa que nenhum acesso ao disco ocorreu em nome do processo de destino naquele momento.

  • Para um canal DirectX, isso significa que nenhum trabalho de GPU foi executado em nome do processo de destino durante esta parte da linha do tempo.

  • Para um canal de marcação, isso significa que nenhum marcador foi gerado.

Botão Exportar (Visualizador de Simultaneidade)

O botão Exportar permite exportar a pilha de chamadas como um arquivo . csv para seus próprios registros ou para uso com outra ferramenta, como o Microsoft Excel.

Apenas Meu Código (Exibição de Threads)

Se você selecionar essa opção, filtrará a pilha de chamadas para mostrar apenas seu código mais um nível de funções chamadas.

Ao ativar essa opção, você pode reduzir significativamente a complexidade da pilha de chamadas e talvez facilitar o diagnóstico de um problema específico.

Em alguns casos, selecionar essa opção pode filtrar a chamada de bloqueio. Se você precisar de detalhes completos da pilha de chamadas para fazer essa determinação, desmarque esta opção para expor a pilha de chamadas completa.

Gerenciar canais

Na Visualização de Threads no Visualizador de Simultaneidade, você pode organizar os canais do seu processo para que possa examinar padrões específicos. Você pode classificar canais, movê-los para cima e para baixo e ocultá-los ou mostrá-los.

Ordenar Por

Você pode usar o controle Classificar por para classificar os threads por critérios diferentes, com base no nível de zoom atual. Isso é especialmente útil quando você está procurando por um padrão específico. Você pode classificar por estes critérios:

Critérios Definition
Hora de Início Classifica os threads por seus horários de início. Esta é a ordem de classificação padrão.
Hora de Término Classifica os threads por seus horários de término.
Execution Classifica os threads pela porcentagem de tempo gasto na execução.
Synchronization Classifica os threads pela porcentagem de tempo gasto na sincronização.
I/O Classifica os threads pela porcentagem de tempo gasto em E/S (leitura e gravação de dados).
Dormir Classifica as threads pela porcentagem de tempo gasto em sleep.
Paging Classifica as threads pela percentagem de tempo gasto na paginação.
Preempção Classifica os threads pela porcentagem de tempo gasto na preempção.
Processamento da interface do usuário Classifica os threads pela porcentagem de tempo gasto no processamento da interface do usuário.

Mover o canal selecionado para cima ou para baixo

Você pode usar esses controles para mover um canal para cima ou para baixo na lista. Por exemplo, poderá posicionar canais relacionados próximos entre si para o ajudar a examinar um padrão específico ou uma relação cruzada entre threads.

Mover o canal selecionado para cima ou para baixo

Você pode mover os canais selecionados para a parte superior ou inferior da lista para que possa examinar um padrão específico ou mover alguns canais para fora do caminho quando examinar outros.

Ocultar canais selecionados

Escolha esse controle quando quiser ocultar canais. Por exemplo, se um thread estiver 100% sincronizado durante a vida do processo gerenciado, você poderá ocultá-lo enquanto analisa outros threads.

Observação

Ocultar um tópico também o remove do tempo de processamento, que é mostrado na legenda ativa e nos relatórios de perfil.

Mostrar todos os canais

Esse controle fica ativo quando um ou mais canais estão ocultos. Se o escolher, todos os elementos ocultos são mostrados e são novamente considerados nos cálculos de tempo.

Mover marcadores para o topo

Se um rastreamento contiver eventos de marcador, você poderá usar esse comando para mover os canais de marcador para a parte superior da linha do tempo. A sua ordem relativa é preservada.

Agrupar marcadores por tópico

Se um rastreamento contiver eventos de marcador, você poderá usar esse comando para agrupar canais de marcador sob o thread que gerou os eventos de marcador. Os canais de disco são movidos para o topo da lista de canais e os canais GPU são movidos para a parte inferior.

Modo de medição ligado/desligado

Usando essa ferramenta, você pode medir com precisão um período de tempo na linha do tempo. Para ativar o modo de medida, clique no botão de medida (que tem um ícone de régua) e arraste na linha do tempo. Ao arrastar, observe que a área abaixo do ponteiro está realçada em amarelo e o tempo medido aparece na barra de ferramentas à direita do botão. Esse valor é calculado dinamicamente à medida que você arrasta para que você possa ver imediatamente quanto tempo um determinado evento está demorando. Quando você solta o botão do mouse, o valor de tempo permanece visível.

Você pode repetir o processo de medição, mas apenas a medição mais recente é mostrada. Clique no botão de medida novamente para desativar o modo de medida.

Percentagem de Redução de Ruído

Por padrão, o valor da configuração Porcentagem de redução de ruído é 2. Somente as entradas que têm uma porcentagem de tempo inclusivo maior ou igual a essa configuração são mostradas na árvore de chamadas. Ao alterar a configuração, você pode controlar o número de entradas exibidas na árvore de chamadas. Por exemplo, alterar o valor para 10 mostrará apenas entradas da árvore de chamadas que tenham um tempo inclusivo maior ou igual a 10%. Ao aumentar o valor da configuração, você pode se concentrar em entradas que têm impactos maiores no desempenho do seu processo.

Relatório baseado no intervalo de tempo visível

A vista Perfil apresenta relatórios baseados no intervalo de tempo e canais atualmente visíveis. Para ver detalhes de diferentes subconjuntos de dados, clique em itens na legenda.

Você pode encontrar mais informações sobre os dados nos relatórios de exibição de threads.

Conector pronto para rosca

Quando você clica em um segmento de bloqueio para ver uma pilha de chamadas e sua pilha de desbloqueio, o conector pronto para thread também pode aparecer. Se o evento de desbloqueio ocorreu em outro thread no processo atual, o conector de prontidão de thread identifica visualmente o thread e o segmento de execução que permitiram ao thread bloqueado retomar a execução.

Cursor da linha do tempo

Ao selecionar um ponto na linha temporal de um segmento de thread em execução, aparece um cursor da linha do tempo acima dele. A pilha de chamadas exibida na guia "Pilha Atual" é a que está mais próxima do ponto no qual clicou no segmento. O cursor é usado para associar a pilha de chamadas, que é exibida na guia Atual, com o instante em que ela foi amostrada. O cursor mostra o local exato da pilha de chamadas, que é a pilha de chamadas mais próxima do local selecionado pelo usuário.

Desbloqueie a pilha

Se o elemento de thread selecionado atualmente representar um segmento bloqueado que mais tarde começou a ser executado depois de ter sido desbloqueado por outro thread no processo atual, a pilha de chamadas para o thread que fez o desbloqueio será mostrada nesta guia.

Perfil visível da linha do tempo

O Perfil da Linha do Tempo Visível para a Visão de Bloqueio de Threads fornece informações estatísticas e links para relatórios. À medida que você aumenta o zoom, diminui o zoom, rola horizontalmente, oculta canais ou mostra canais, os números na legenda ativa mudam para refletir o que está atualmente em exibição. Para exibir um relatório sobre um item na Legenda, clique no item.

Controle de zoom (exibição de tópicos)

O controle de zoom é um controle deslizante que ajuda você a aumentar e diminuir o zoom na linha do tempo para que você possa se concentrar em áreas de interesse particular. Como esse controle aumenta o zoom no centro da exibição da linha do tempo, centralize a área de interesse antes de aumentar o zoom.

Aumentar o zoom arrastando a vista da linha cronológica

Aumentar o zoom arrastando a vista da linha cronológica cria uma área realçada a amarelo. Quando se solta o botão do rato, a visualização da linha do tempo faz zoom sobre o intervalo selecionado.

Aumente e diminua o zoom usando a roda do mouse

Clique em qualquer ponto da linha cronológica (para garantir que tem o foco do rato) e, em seguida, prima Ctrl e mova a roda do rato (para a frente aumenta o zoom; para trás diminui o zoom).