Maneiras de visualizar dados de eventos em busca de problemas de desempenho

10

Estou tentando otimizar um aplicativo MPI com um padrão de comunicação altamente assíncrono. Cada classificação possui uma lista de itens a serem calculados e envia mensagens conforme necessário, se as entradas ou saídas residirem em uma classificação diferente. Além disso, cada classificação é encadeada (atualmente com um encadeamento de comunicação e 5 trabalhadores).

Eu instrumentei o código com timers em torno das diferentes partes críticas de desempenho, o que me fornece uma lista de triplos (início, fim, tipo) para cada thread. Traçados de maneira óbvia, com o tempo como eixo horizontal, a classificação e a linha como a vertical e a cor indicando o que cada linha está fazendo atualmente, recebo uma imagem como essa para 16 fileiras com 6 linhas / classificação:

Pentago rank e histórico de threads

Minha pergunta é: quais são outras maneiras de visualizar esses dados que podem ajudar a identificar problemas de desempenho? Alguém tem um tipo favorito de plot que eles usam ao criar um perfil de aplicativos assíncronos?

Esse conjunto de dados é limitado por não conhecer a estrutura do fluxo de dados, mas eu gostaria de obter o máximo de informações possível antes de tentar coletar algo mais complicado.

A imagem não compactada está aqui , caso alguém queira olhar em volta (falha ao fazer o upload pela rota normal). Infelizmente, o Firefox não aceita, mesmo que eu acredite que seja válido, possivelmente porque é muito grande.

Geoffrey Irving
fonte
Eu tive alguns problemas para obter meu navegador ou quase qualquer outro programa para carregar a imagem grande. No final, o gimp fez isso, mas você pode considerar novamente as opções de tamanho ou formato de arquivo.
Pedro
Me desculpe por isso. Eu acho que a imagem é válida, já que o Firefox me dá os mesmos erros que estão sendo executados através do convert (ImageMagick). Possivelmente excede algum limite de tamanho arbitrário.
Geoffrey Irving

Respostas:

4

Passo muito tempo escrevendo e depurando código paralelo, com memória compartilhada e / ou distribuída, mas sem conhecer seu problema específico, só posso lhe dizer o que funciona melhor para mim.

Sabendo que rotinas tomar quanto tempo é uma coisa importante, se você está olhando para a eficiência computacional, mas se você está preocupado com a eficiência paralela, então você deve estar mais preocupado com o que o seu código está fazendo quando é não fazer qualquer cálculo. É como se preocupar com o que as crianças estão fazendo quando está muito quieto ...

Como você está usando uma abordagem híbrida de memória compartilhada / distribuída, acho que seu código está, nos espaços em branco, aguardando uma chamada MPI ou uma variável mutex / condition. Você também pode agrupar essas chamadas em timers, e isso lhe dará uma imagem melhor do que está atrasando você, por exemplo, se é sempre a mesma condicional ou sempre a mesma em MPI_REDUCEque seus threads ficam presos.

Um software que uso com bastante frequência é o Intel Vtune Amplifier XE . Ele possui um bom recurso / opção de plotagem que visualiza a simultaneidade do encadeamento. O programa desenhará um gráfico muito semelhante ao seu, mas quando um encadeamento aguarda uma variável mutex ou condição, ele desenha uma linha diagonal do encadeamento em espera, no momento em que começou a aguardar, para o encadeamento que realmente liberou o mutex ou sinalizou a condição que estava aguardando, no momento em que foi liberada / sinalizada. Isso pode ser bastante confuso, mas faz com que gargalos apareçam imediatamente.

Finalmente, também coleciono estatísticas em massa, por exemplo, para cada chamada mutex / sinal / MPI, quais foram os tempos médio e máximo de espera? Qual é o histograma dos tempos de espera coletados? Enquanto o enredo fornece uma boa visão geral, ele pode ficar bastante confuso quando se trata de detalhes finos.

Finalmente, uma pergunta que não deve ser subestimada: como você está coletando seus horários? O seu timer não é intrusivo o suficiente para não influenciar o seu código? Eu uso a contagem de instruções da CPU sempre que possível, ou seja, RDTSCem arquiteturas x86. Isso geralmente adiciona apenas uma única instrução ao seu código.

Pedro
fonte
Os dados já possuem bloqueios em torno de todas as esperas; no diagrama, eles são mostrados em branco para threads de trabalho ocioso e amarelo para espera de threads de comunicação. Infelizmente, todas as esperas no encadeamento de comunicação ocorrem em um único MPI_Waitsome devido à assincronia. O Vtune não se aplica nesse caso, pois o desempenho puramente encadeado é essencialmente perfeito, mas obrigado pelo ponteiro. A sugestão de histograma também é boa.
Geoffrey Irving
Quanto à sobrecarga de tempo: estou usando gettimeofday, o que é necessário pelo menos nas seções ociosas, pois lá utilizo variáveis ​​de condição pthread. A contagem de instruções da CPU pode ser feita para funcionar em tal situação? A sobrecarga já é baixa o suficiente, mas menor seria certamente melhor.
Geoffrey Irving
11
@GeoffreyIrving: Sim, você pode usá-los, mas eles só fazem sentido em CPUs que possuem o constant_tscsinalizador definido (verificação /proc/cpuinfo) e se você usar cada trava para um núcleo específico, ou seja, cada segmento sempre lê o mesmo registro do mesmo núcleo, por exemplo, usando pthread_setaffinity_np. Observe que o último é específico do Linux e, portanto, não é portátil.
Pedro Pedro
@GeoffreyIrving: Mesmo se você estiver esperando por algum evento não divulgado MPI_Waitsome, ainda poderá registrar quais solicitações realmente chegaram e de onde. Esta informação pode ou não ser de uso ...
Pedro
5

Às vezes, você pode obter uma visão alternativa dos problemas de desempenho por meio de uma análise de recursos de alto nível: Existe um gargalo relevante, como a largura de banda da memória? Todo segmento de trabalho faz a mesma quantidade de trabalho? Esses dados podem ser coletados facilmente com o likwid-perfctr do projeto de código do Google LIKWID do conjunto de ferramentas LIKWID . Se o perfil é tal que existem muitos pontos de acesso diferentes, pode ser necessário enfrentá-los um por um. Também pode haver problemas diferentes, dependendo de quantos threads / processos são usados.

Georg Hager
fonte
No interesse da divulgação perfeita, Georg trabalha no projeto LIKWID e solicitei essa resposta porque queria complementar a grande resposta de Pedro com outra perspectiva (e uma ótima ferramenta disponível gratuitamente).
Aron Ahmadia 11/09/12
2

Quando tenho um problema em uma rede de processos altamente assíncronos governados por mensagens ou eventos, uso um método que não é fácil, mas é eficaz. Isso envolvia obter registros dos processos com registro de data e hora, mesclá-los em uma linha do tempo comum e rastrear o progresso de algumas mensagens à medida que desencadeiam atividades, desencadeando outras mensagens. O que estou procurando é um atraso entre o momento em que uma mensagem é recebida e a hora em que é respondida, e a compreensão do motivo do atraso. Quando um problema é encontrado, ele é corrigido e o processo é repetido. Dessa forma, você pode obter um desempenho realmente satisfatório.

É importante ver como isso difere das abordagens em que você mede, mede, mede. A única coisa que a medição pode lhe dizer é para onde não procurar. O ajuste de desempenho real requer uma análise cuidadosa dos detalhes, de uma perspectiva temporal. O que você está procurando não é onde o tempo é gasto, mas onde é gasto desnecessariamente.

Boa sorte.

Mike Dunlavey
fonte
Em outras palavras, não há visualização útil dos dados que tenho. :) Jed Brown sugeriu o Jumpshot (e utilitários associados) como uma maneira de coletar e visualizar os dados que você sugere, então analisarei isso.
Geoffrey Irving
@ Geof: Boa sorte com a visualização. A única ferramenta que eu teria achado útil é algo para coletar e mesclar os logs de eventos, para que eu possa seguir o caminho de uma ou mais solicitações conforme ele percorre os vários threads, porque essa é a única maneira que eu conheço para detectar desnecessários atrasos. É disso que consiste qualquer problema de desempenho - atrasos desnecessários.
Mike Dunlavey