Criação de perfil de código CFD com Callgrind

16

Estou usando o Valgrind + Callgrind para criar um perfil para o solucionador que escrevi. Conforme o manual do usuário do Valgrind, compilei meu código com as opções de depuração para o compilador:

"Sem as informações de depuração, a melhor ferramenta que o Valgrind poderá fazer é adivinhar a qual função um determinado código pertence, o que torna as mensagens de erro e a saída de criação de perfis quase inúteis. Com -g, você receberá mensagens que apontam diretamente para as linhas de código fonte relevantes ".

Manual do Valgrind

Quando compilados com a opção de depuração, os códigos ficam muito mais lentos. O código CFD fica REALMENTE lento, mesmo para casos pequenos quando compilados com sinalizadores de depuração. Valgrind torna 40x mais lento (consulte o manual 1 ).

  1. Quais ferramentas você está usando para criação de perfil de código (criação de perfil, não avaliação de desempenho)?

  2. Quanto tempo você deixa o código rodar (estatísticas: quantas etapas de tempo)?

  3. Qual o tamanho dos casos (se o caso se encaixa no cache, o solucionador é de ordens de magnitude mais rápido, mas depois sentirei falta dos processos relacionados à memória)?

tmaric
fonte
3
Você pode compilar o código com símbolos de depuração e otimização ativados. Ainda, 40x através do valgrind (que simula todo o acesso à memória) não é irracional.
Aron Ahmadia
Obrigado, é isso que eu também li ... o que eu gostaria de saber são informações sobre as experiências diárias de criação de perfil (com o valgrind, de preferência): quanto tempo é normal esperar pelos relatórios, quantas iterações conta que eu preciso, o que eu posso excluir ... etc ...
tmaric
Sua pergunta também é um pouco ampla. Eu recomendo que você edite sua pergunta para focar nas Q2.1 e Q2.2, pois a Q1 é uma pergunta completamente diferente (fico feliz em perguntar separadamente, é uma boa pergunta, mas faça a frase como "Quais ferramentas você use para resolver o problema X ", onde X é bem descrito!), enquanto Q2 por si só é muito geral.
Aron Ahmadia
Você também pode editar para nome callgrind, cachegrindou massif. Muitas pessoas associam o Valgrind apenas à ferramenta padrão ( memcheck). Como um sistema de criação de perfil baseado em emulação (em vez de baseado em interrupção), você não precisa executar por um longo tempo.
precisa
@ Aron & Jed: obrigado pelas dicas, eu editei a pergunta. :)
tmaric

Respostas:

11

T1: Quais ferramentas você está usando para criação de perfil de código (criação de perfil, não avaliação de desempenho)?

P2: quanto tempo você deixa o código executar (estatísticas: quantas etapas de tempo)?

Q3: Qual é o tamanho dos casos (se o caso couber no cache, o solucionador é de ordens de magnitude mais rápido, mas sentirei falta dos processos relacionados à memória)?

Aqui está um exemplo de como eu faço isso.

Separei o benchmarking (vendo quanto tempo leva) do perfil (identificando como torná-lo mais rápido). Não é importante que o criador de perfil seja rápido. É importante que ele lhe diga o que corrigir.

Eu nem gosto da palavra "criação de perfil" porque evoca uma imagem como um histograma, onde há uma barra de custo para cada rotina ou "gargalo" porque implica que há apenas um pequeno local no código que precisa ser fixo. Ambas as coisas implicam algum tipo de tempo e estatística, para os quais você assume que a precisão é importante. Não vale a pena abrir mão da percepção da precisão do tempo.

O método usado é uma pausa aleatória, e há um estudo de caso completo e uma apresentação de slides aqui . Parte da visão de mundo dos gargalos do criador de perfil é que, se você não encontrar nada, não há nada a ser encontrado, e se você encontrar algo e obter uma certa porcentagem de aceleração, declara vitória e sai. Os fãs do Profiler quase nunca dizem quanta aceleração recebem, e os anúncios mostram apenas problemas artificialmente criados para serem fáceis de encontrar. A pausa aleatória encontra os problemas, sejam eles fáceis ou difíceis. A solução de um problema expõe outros, para que o processo possa ser repetido, para aumentar a velocidade.

Na minha experiência com vários exemplos, veja como ele funciona: posso encontrar um problema (pausando aleatoriamente) e corrigi-lo, obtendo uma aceleração de alguns por cento, digamos 30% ou 1,3x. Então eu posso fazer isso de novo, encontrar outro problema e corrigi-lo, obtendo outro aumento de velocidade, talvez menos de 30%, talvez mais. Então eu posso fazê-lo novamente, várias vezes, até realmente não encontrar mais nada para consertar. O fator de aceleração final é o produto em execução dos fatores individuais e, em alguns casos, pode ser incrivelmente grande - ordens de magnitude.

INSERIDO: Apenas para ilustrar este último ponto. Há um exemplo detalhado aqui , com apresentação de slides e todos os arquivos, mostrando como uma aceleração de 730x foi alcançada em uma série de remoções de problemas. A primeira versão levou 2700 microssegundos por unidade de trabalho. O problema A foi removido, diminuindo o tempo para 1800 e ampliando as porcentagens de problemas restantes em 1,5x (2700/1800). Então B foi removido. Esse processo continuou por seis iterações, resultando em quase três ordens de aceleração de magnitude. Mas a técnica de criação de perfil deve ser realmente eficaz, porque se nenhum desses problemas for encontrado, ou seja, se você chegar a um ponto em que você pensa incorretamente que nada mais pode ser feito, o processo será interrompido.

Descrição da remoção de vários problemas para obter grande aceleração

INSERIDO: Dito de outra maneira, aqui está um gráfico do fator de aceleração total à medida que problemas sucessivos são removidos:

insira a descrição da imagem aqui

Assim, no primeiro trimestre, para o benchmarking basta um temporizador simples. Para "criação de perfil", uso uma pausa aleatória.

Q2: Eu ofereço carga de trabalho suficiente (ou apenas coloco um loop em torno dela) para que ela demore o suficiente para fazer uma pausa.

Q3: De qualquer forma, ofereça uma carga de trabalho realisticamente grande para não perder problemas de cache. Eles aparecerão como exemplos no código que faz a busca na memória.

Mike Dunlavey
fonte
Mike, você prefere como fazer uma pausa aleatória na ausência de um IDE visual? Esse processo pode ser automatizado de alguma forma?
Matthew Emmett
@ Matthew: Eu entendo que existem ferramentas como pstacke lsstack, mas realmente considero esse um processo mais comum com a depuração. Portanto, mesmo que o melhor depurador que eu possa usar seja gdb, ele faz o trabalho. Com um depurador, você pode examinar os dados e isso pode fazer a diferença quando a pilha sozinha não informa o suficiente.
Mike Dunlavey
9

O perfilador do pobre homem é basicamente um gdbscript que mostra a pilha de chamadas. Você ainda precisará ter símbolos de depuração. Ainda é lento, mas como não implementa uma máquina virtual para executar o código, geralmente é mais rápido callgrinde adequado à tarefa.

Encontrei analisadores de física de partículas com sucesso modesto (ou seja, demonstrei que o código não apresentava nenhum ponto de acesso horrível e a otimização exigiria um algoritmo melhor).

dmckee
fonte
11
+ Ausência de evidência não é evidência de ausência :) O que o profiler do pobre homem deve fazer é pegar menos traços e não colapsá-los, mas permita que você os veja. O olho humano é muito melhor na detecção de padrões úteis do que estimativas simples de tempo de função, e se você vir algo que possa melhorar em apenas 2 amostras, isso ajudará significativamente. A fração X que ele salvará é uma distribuição beta no modo 2 / N, onde N é quantos traços você examinou e o fator de aceleração será 1 / (1-X), que pode ser grande.
precisa saber é o seguinte
2

Para adicionar as ótimas respostas disponíveis, existe uma ferramenta desenvolvida na Rice que automatiza a amostragem de pilhas e, portanto, possui muito pouco custo adicional:

http://hpctoolkit.org/

Reid.Atcheson
fonte
Parece bom, embora (desculpe) eu coloquei meu chapéu de fogo aqui. Não sintonizo código otimizado para compilador porque é difícil ver o que está acontecendo no código desconfigurado. As coisas que eu estou podando não são coisas com as quais o otimizador possa lidar - como chamar expe logcom os mesmos argumentos repetidamente, ou operações de matriz gastando todo o seu tempo decodificando opções. Eu sintonizo o máximo que posso e ligo -O3.
precisa saber é o seguinte
Ferramentas são ferramentas e são úteis apenas se o usuário souber e entender suas limitações. Acho que nunca haverá um "perfil perfeito" que removerá completamente o usuário da equação no que diz respeito a entender sua saída e saber como usar as informações.
precisa saber é o seguinte
1

O Allinea MAP é um perfilador de amostragem desenvolvido e suportado comercialmente e, portanto, como o HPC Toolkit sugerido em uma resposta anterior, pode ser executado em trabalhos de tamanho de produção, se desejar.

Esse tipo de ferramenta aponta para gargalos na CPU ou má comunicação MPI, mas também toda a supervisão de criação de perfil de todo o trabalho pode ser inestimável para encontrar problemas surpreendentes.

Muitas vezes, existem frutos de desempenho pouco exigentes que estão fora do núcleo do código CFD, em áreas que não eram esperadas. A amostragem aleatória de pilhas é - feita manualmente com o GDB ou com ferramentas como o HPC Toolkit e o Allinea MAP - a melhor maneira de encontrá-las. Se algo é importante para o desempenho, ele será exibido.

David
fonte