@Gregory - Estou inclinado a concordar, e talvez ele deve contribuir com respostas de sua autoria, 229 vs 6, todos os 6 dessas respostas sendo a suas próprias perguntas ...
Jean-Bernard Pellerin
5
Como essa pergunta pode não ser construtiva?
JohnTortugo
Respostas:
73
O Valgrind possui um perfilador de contagem de instruções com um visualizador muito bom chamado KCacheGrind . Como Mike Dunlavey recomenda, Valgrind conta a fração de instruções para as quais um procedimento está ativo na pilha, embora lamento dizer que parece estar confuso na presença de recursão mútua. Mas o visualizador é muito bom e tem anos-luz à frente gprof.
@ Norman: ++ Essa confusão sobre recursão parece endêmica para sistemas que têm o conceito de propagar tempos entre nós em um gráfico. Também acho que o tempo do relógio de parede geralmente é mais útil que o tempo de instrução da CPU, e as linhas de código (instruções de chamada) são mais úteis que os procedimentos. Se forem coletadas amostras de pilha em horários aleatórios, o custo fracionário de uma linha (ou procedimento ou qualquer outra descrição que você possa fazer) é simplesmente estimado pela fração de amostras que a exibem.
21118 Mike Dunlavey
1
... Estou enfatizando as instruções de chamada, mas isso se aplica a todas as instruções. Se houver um gargalo de ponto de acesso honesto, como um tipo de bolha de uma grande variedade de números, as instruções de comparação / salto / troca / incremento do loop interno estarão na parte superior / inferior de quase todas as amostras de pilha . Mas (especialmente quando o software cresce e quase nenhuma rotina tem muito tempo "próprio"), na verdade, muitos problemas são instruções de chamada, solicitando um trabalho que, quando fica claro quanto custa, realmente não precisa ser feito.
O gprof (leia o artigo) existe por razões históricas. Se você acha que isso o ajudará a encontrar problemas de desempenho, nunca foi anunciado como tal. Aqui está o que o artigo diz:
O perfil pode ser usado para comparar e avaliar os custos de várias implementações.
Não diz que pode ser usado para identificar as várias implementações a serem avaliadas, embora implique que poderia, em circunstâncias especiais:
especialmente se pequenas partes do programa dominam seu tempo de execução.
E os problemas que não são tão localizados? Isso não importa? Não coloque no gprof expectativas que nunca foram reivindicadas por isso. É apenas uma ferramenta de medição e apenas de operações ligadas à CPU.
Há uma observação simples sobre os programas. Em uma determinada execução, toda instrução é responsável por uma fração do tempo total (especialmente callinstruções), no sentido de que, se não estivesse lá, o tempo não seria gasto. Durante esse tempo, a instrução está na pilha **. Quando isso é compreendido, você pode ver que -
O gprof incorpora certos mitos sobre desempenho, como:
essa amostragem de contador de programa é útil.
Só é útil se você tiver um gargalo de ponto de acesso desnecessário, como um tipo de bolha de uma grande variedade de valores escalares. Assim que você, por exemplo, alterá-lo para uma classificação usando comparação de cadeias, ainda é um gargalo, mas a amostragem do contador de programa não a verá porque agora o ponto de acesso está na comparação de cadeias. Por outro lado, se fosse amostrar o contador de programa estendido (a pilha de chamadas), o ponto no qual a comparação de cadeia é chamada, o loop de classificação, é claramente exibido. De fato, o gprof foi uma tentativa de remediar as limitações da amostragem somente para PC.
que as funções de temporização são mais importantes do que capturar linhas de código demoradas.
A razão para esse mito é que o gprof não foi capaz de capturar amostras de pilha; portanto, ele cronometra funções, conta suas invocações e tenta capturar o gráfico de chamada. No entanto, uma vez que uma função dispendiosa é identificada, você ainda precisa procurar dentro dela as linhas responsáveis pelo tempo. Se houvesse amostras de pilha que você não precisaria procurar, essas linhas estariam nas amostras. (Uma função típica pode ter instruções de 100 a 1000. Uma chamada de função é 1 instrução; portanto, algo que localiza chamadas caras é de 2 a 3 ordens de magnitude mais precisas.)
que o gráfico de chamadas é importante.
O que você precisa saber sobre um programa não é onde ele gasta seu tempo, mas por que. Quando se gasta tempo em uma função, cada linha de código na pilha fornece um link na cadeia de raciocínio sobre o motivo de ela estar lá. Se você conseguir ver apenas parte da pilha, poderá ver apenas parte do motivo, portanto não poderá ter certeza se esse tempo é realmente necessário. O que o gráfico de chamadas diz a você? Cada arco informa que alguma função A estava no processo de chamar alguma função B por uma fração do tempo. Mesmo que A possua apenas uma linha de código chamada B, essa linha fornece apenas uma pequena parte do motivo. Se você tiver sorte o suficiente, talvez essa linha tenha um motivo insuficiente. Normalmente, você precisa ver várias linhas simultâneas para encontrar um motivo ruim, se houver. Se A ligar para B em mais de um local, será informado ainda menos.
essa recursão é uma questão complicada e confusa.
Isso ocorre apenas porque o gprof e outros criadores de perfil percebem a necessidade de gerar um gráfico de chamada e, em seguida, atribuem tempos aos nós. Se houver amostras da pilha, o custo de tempo de cada linha de código que aparece nas amostras é um número muito simples - a fração de amostras em que está. Se houver recursão, uma determinada linha poderá aparecer mais de uma vez em uma amostra.
Não importa. Suponha que amostras sejam colhidas a cada N ms e a linha apareça em F% delas (isoladamente ou não). Se essa linha não puder demorar (por exemplo, excluindo-a ou ramificando-a), essas amostras desaparecerão e o tempo será reduzido em F%.
que a precisão da medição do tempo (e, portanto, um grande número de amostras) é importante.
Pense nisso por um segundo. Se uma linha de código estiver em três amostras em cinco, se você puder dispará-la como uma lâmpada, isso é aproximadamente 60% menos tempo que seria usado. Agora, você sabe que, se você tiver tirado 5 amostras diferentes, poderá vê-lo apenas 2 vezes ou até 4. Portanto, essa medição de 60% é mais como uma faixa geral de 40% a 80%. Se fosse apenas 40%, você diria que o problema não vale a pena consertar? Então, qual é a precisão do ponto no tempo, quando o que você realmente deseja é encontrar os problemas ? 500 ou 5000 amostras teriam medido o problema com maior precisão, mas não o teriam encontrado com mais precisão.
que a contagem de chamadas de instruções ou funções é útil.
Suponha que você saiba que uma função foi chamada 1000 vezes. Você pode dizer com isso que fração do tempo custa? Você também precisa saber quanto tempo leva para executar, em média, multiplicá-lo pela contagem e dividir pelo tempo total. O tempo médio de chamada pode variar de nanossegundos a segundos, portanto, a contagem por si só não conta muito. Se houver amostras de pilha, o custo de uma rotina ou de qualquer instrução é apenas a fração de amostras em que está. Essa fração de tempo é o que poderia, em princípio, ser salvo em geral, se a rotina ou a declaração pudesse ser feita com rapidez, e é essa a relação mais direta com o desempenho.
que as amostras não precisam ser coletadas quando bloqueadas
As razões para esse mito são duplas: 1) a amostragem por PC não faz sentido quando o programa está aguardando e 2) a preocupação com a precisão do tempo. No entanto, para (1) o programa pode muito bem estar aguardando algo que ele solicitou, como E / S de arquivo, que você precisa saber e quais exemplos de pilha revelam. (Obviamente, você deseja excluir amostras enquanto aguarda a entrada do usuário.) Para (2) se o programa estiver aguardando simplesmente por causa da concorrência com outros processos, isso presumivelmente acontece de maneira bastante aleatória enquanto estiver em execução. Portanto, embora o programa possa demorar mais, isso não terá um grande efeito sobre a estatística que importa, a porcentagem de tempo em que as instruções estão na pilha.
que o "tempo próprio" é importante
O tempo próprio só faz sentido se você estiver medindo no nível da função, não no nível da linha, e acha que precisa de ajuda para discernir se o tempo da função entra na computação puramente local versus nas rotinas chamadas. Ao resumir no nível da linha, uma linha representa o tempo próprio, se estiver no final da pilha, caso contrário, representa o tempo inclusivo. De qualquer forma, o que custa é a porcentagem de amostras de pilha em que está, de modo que a localiza para você em ambos os casos.
que as amostras precisam ser colhidas em alta frequência
Isso vem da ideia de que um problema de desempenho pode ter ação rápida e que as amostras precisam ser frequentes para atingi-lo. Mas, se o problema estiver custando 20%, digamos, de um tempo total de execução de 10 segundos (ou o que seja), cada amostra nesse tempo total terá 20% de chance de atingi-lo, não importa se o problema ocorrer em uma única peça como essa .....XXXXXXXX........................... .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 amostras, 4 ocorrências)
ou em várias partes pequenas como esta X...X...X.X..X.........X.....X....X..... .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 amostras, 3 ocorrências)
De qualquer forma, o número de ocorrências será em média de 1 em 5, não importa quantas amostras sejam coletadas, ou Quão poucos. (Média = 20 * 0,2 = 4. Desvio padrão = +/- sqrt (20 * 0,2 * 0,8) = 1,8.)
que você está tentando encontrar o gargalo
como se houvesse apenas um. Considere a seguinte linha do tempo de execução: vxvWvzvWvxvWvYvWvxvWv.vWvxvWvYvW
Consiste em um trabalho útil real, representado por .. Existem problemas de desempenho que vWxYzlevam 1/2, 1/4, 1/8, 1/16, 1/32 do tempo, respectivamente. A amostragem encontra vfacilmente. Ele é removido, deixando xWzWxWYWxW.WxWYW
Agora o programa leva metade do tempo para ser executado, e agora Wleva metade do tempo e é encontrado com facilidade. Ele é removido, deixando xzxYx.xY
Esse processo continua, cada vez que você remove o maior problema de desempenho, em porcentagem, até que nada seja removido. Agora, a única coisa executada é a .que é executada em 1/32 do tempo usado pelo programa original. Este é o efeito de ampliação, pelo qual remover qualquer problema aumenta o restante, em porcentagem, porque o denominador é reduzido.
Outro ponto crucial é que todos os problemas devem ser encontrados - sem nenhum dos 5. Qualquer problema não encontrado e corrigido reduz severamente a taxa de aceleração final. Apenas encontrar alguns, mas não todos, não é "bom o suficiente".
ADICIONADO: Gostaria apenas de salientar uma das razões pelas quais o gprof é popular - está sendo ensinado, provavelmente porque é gratuito, fácil de ensinar e já existe há muito tempo. Uma rápida pesquisa no Google localiza algumas instituições acadêmicas que ensinam (ou parecem):
berkeley bu clemson colorado duque earlham fsu indiana mit msu ncsa.illinois ncsu nyu ou princeton psu stanford ucsd umd umich utah utexas utk utk wustl
** Com exceção de outras maneiras de solicitar que o trabalho seja feito, isso não deixa rastro, indicando o porquê , como a postagem de mensagens.
@ Norman: Eu fiz um criador de perfil baseado nisso, em C para DOS, por volta de 93. Eu o chamei de mais um analisador de desempenho e o demonstrei nas reuniões do IEEE, mas isso foi o mais longe. Existe um produto da RotateRight chamado Zoom que não está muito longe. No * nix, o pstack é bom para fazer isso manualmente. Minha lista de tarefas pelo trabalho (produtos farmacêuticos no Windows) tem cerca de um quilômetro e meio de comprimento, o que impede projetos divertidos, sem mencionar a família. Isso pode ser útil: stackoverflow.com/questions/1777669/… #
Mike Dunlavey
6
Eu sempre achei os profilers não tão úteis para corrigir código lento e, em vez disso, usei bits seletivos de código de depuração para medir o tempo gasto por um grupo de instruções de minha escolha, muitas vezes auxiliado por algumas pequenas macros triviais ou qualquer outra coisa. Nunca me levou muito tempo para encontrar o culpado, mas sempre fiquei envergonhado com a minha abordagem de "peles de urso e facas de pedra" quando "todo mundo" (tanto quanto eu sei) usa as ferramentas sofisticadas. Obrigado por me mostrar por que nunca consegui obter as informações necessárias do criador de perfil. Essa é uma das idéias mais importantes que eu já vi no SO. Bem feito!
Wayne Conrad
7
@osgx: Não quero rasgar nada. É como um automóvel favorito antigo, simples e robusto, mas há coisas que ele não faz, e precisamos estar cientes disso, e não apenas isso, precisamos despertar dos mitos. Entendo que em algumas plataformas pode ser difícil obter amostras de pilha, mas se um problema é tal que o gprof não o encontra, o fato de ser a única ferramenta é um pequeno conforto.
Mike Dunlavey
2
@ Andrew: ... e se esse motivo se aplicar a uma fração significativa de amostras (como mais de 1), as linhas de código que poderiam eliminar essa atividade estão nessas amostras. Um gráfico pode dar uma dica disso, mas um número não grande de amostras de pilha simplesmente as mostrará.
Mike Dunlavey
2
@ Matt: Exemplos de problemas de desempenho de E / S encontrados desta maneira: 1) imprimir mensagens de log em um arquivo ou no console, que erroneamente foi considerado insignificante. 2) Convertendo entre texto e dobra em IO numérico. 3) E / S subterrâneas que extraem seqüências internacionalizadas durante a inicialização; as sequências que resultam não precisavam ser internacionalizadas. Eu bati muitos exemplos como estes.
precisa saber é o seguinte
63
Como não vi aqui nada sobre o perfque é uma ferramenta relativamente nova para criar um perfil dos aplicativos do kernel e do usuário no Linux, decidi adicionar essas informações.
Você pode usar perfse o seu Kernel Linux for maior que 2.6.32 ou oprofilese for mais antigo. Ambos os programas não exigem que você instrumente seu programa (como gprofexige). No entanto, para obter o gráfico de chamadas corretamente, perfvocê precisa criar seu programa -fno-omit-frame-pointer. Por exemplo: g++ -fno-omit-frame-pointer -O2 main.cpp.
Você pode ver a análise "ao vivo" do seu aplicativo com perf top:
sudo perf top -p `pidof a.out` -K
Ou você pode gravar dados de desempenho de um aplicativo em execução e analisá-los depois:
Eu uso libmalloc_minimial.sodesde que ele é compilado -fno-omit-frame-pointerenquanto o libc malloc parece ser compilado sem essa opção. Então eu executo meu programa de teste
./my_test 100000000
Depois, registro os dados de desempenho de um processo em execução:
perf record -g -p `pidof my_test` -o ./my_test.perf.data sleep 30
Acabei de dar o seu exemplo e tirei 5 stackshots. Aqui está o que eles encontraram: 40% (aproximadamente) do tempo f1estava chamando delete. 40% (aproximadamente) do tempo process_requestestava ligando delete. Boa parte do restante foi gasta em new. As medições são difíceis, mas os pontos ativos são identificados.
precisa saber é o seguinte
O que é um stackshot? É isso que pstackproduz?
2
As in my answer, you run it under a debugger and hit ^C at a random time and capture the stack trace. 1) Acho que sua técnica não é útil quando você precisa analisar problemas de desempenho para um programa em execução no servidor do seu cliente. 2) Não tenho certeza de como você aplica essa técnica para obter informações de um programa com muitos threads que lidam com solicitações diferentes. Quero dizer, quando a imagem geral é bastante complicada.
2
Quanto ao número 1. Às vezes, os clientes ligam e dizem que seu programa funciona lentamente. Você não pode dizer imediatamente isso the problem is outside your code, pode? Como você pode precisar de algumas informações para apoiar seu argumento. Nessa situação, em algum momento você pode precisar criar um perfil do seu aplicativo. Você não pode simplesmente pedir ao seu cliente para iniciar o gdb, pressionar ^ C e obter pilhas de chamadas. Esse foi o meu ponto. Este é um exemplo spielwiese.fontein.de/2012/01/22/… . Eu tive esse problema e a criação de perfil ajudou muito.
2
Quanto ao # 2. Simplificar é uma boa abordagem, eu concordo. Às vezes funciona. Se um problema de desempenho ocorrer apenas no servidor de um cliente e você não puder reproduzi-lo no servidor, os perfis serão úteis.
21
Experimente o OProfile . É uma ferramenta muito melhor para criar um perfil do seu código. Eu também sugeriria o Intel VTune .
As duas ferramentas acima podem reduzir o tempo gasto em uma linha de código específica, anotar seu código, mostrar montagem e quanta instrução específica leva. Além da métrica de tempo, você também pode consultar contadores específicos, como hits de cache, etc.
Ao contrário do gprof, você pode criar um perfil de qualquer processo / binário em execução no seu sistema usando um dos dois.
Como também mencionado na resposta da valgrind, o Zoom do RotateRight ( rotateright.com ) fornece uma interface muito melhor e permite a criação de perfil remoto.
21410 JanePhanie
não gostava de oprofile, parecia casual
Matt Joiner
@ Matt algum ponto em particular?
Anycorn
Não foi capaz de lidar com mais de 10s de execução antes de gerar estouros de estatísticas, a saída não foi particularmente útil e a documentação é terrível.
Respostas:
O Valgrind possui um perfilador de contagem de instruções com um visualizador muito bom chamado KCacheGrind . Como Mike Dunlavey recomenda, Valgrind conta a fração de instruções para as quais um procedimento está ativo na pilha, embora lamento dizer que parece estar confuso na presença de recursão mútua. Mas o visualizador é muito bom e tem anos-luz à frente
gprof
.fonte
O gprof (leia o artigo) existe por razões históricas. Se você acha que isso o ajudará a encontrar problemas de desempenho, nunca foi anunciado como tal. Aqui está o que o artigo diz:
Não diz que pode ser usado para identificar as várias implementações a serem avaliadas, embora implique que poderia, em circunstâncias especiais:
E os problemas que não são tão localizados? Isso não importa? Não coloque no gprof expectativas que nunca foram reivindicadas por isso. É apenas uma ferramenta de medição e apenas de operações ligadas à CPU.
Tente isso em vez disso.
Aqui está um exemplo de uma aceleração de 44x.
Aqui está uma aceleração de 730x.
Aqui está uma demonstração em vídeo de 8 minutos.
Aqui está uma explicação das estatísticas.
Aqui está uma resposta para as críticas.
Há uma observação simples sobre os programas. Em uma determinada execução, toda instrução é responsável por uma fração do tempo total (especialmente
call
instruções), no sentido de que, se não estivesse lá, o tempo não seria gasto. Durante esse tempo, a instrução está na pilha **. Quando isso é compreendido, você pode ver que -O gprof incorpora certos mitos sobre desempenho, como:
essa amostragem de contador de programa é útil.
Só é útil se você tiver um gargalo de ponto de acesso desnecessário, como um tipo de bolha de uma grande variedade de valores escalares. Assim que você, por exemplo, alterá-lo para uma classificação usando comparação de cadeias, ainda é um gargalo, mas a amostragem do contador de programa não a verá porque agora o ponto de acesso está na comparação de cadeias. Por outro lado, se fosse amostrar o contador de programa estendido (a pilha de chamadas), o ponto no qual a comparação de cadeia é chamada, o loop de classificação, é claramente exibido. De fato, o gprof foi uma tentativa de remediar as limitações da amostragem somente para PC.
que as funções de temporização são mais importantes do que capturar linhas de código demoradas.
A razão para esse mito é que o gprof não foi capaz de capturar amostras de pilha; portanto, ele cronometra funções, conta suas invocações e tenta capturar o gráfico de chamada. No entanto, uma vez que uma função dispendiosa é identificada, você ainda precisa procurar dentro dela as linhas responsáveis pelo tempo. Se houvesse amostras de pilha que você não precisaria procurar, essas linhas estariam nas amostras. (Uma função típica pode ter instruções de 100 a 1000. Uma chamada de função é 1 instrução; portanto, algo que localiza chamadas caras é de 2 a 3 ordens de magnitude mais precisas.)
que o gráfico de chamadas é importante.
O que você precisa saber sobre um programa não é onde ele gasta seu tempo, mas por que. Quando se gasta tempo em uma função, cada linha de código na pilha fornece um link na cadeia de raciocínio sobre o motivo de ela estar lá. Se você conseguir ver apenas parte da pilha, poderá ver apenas parte do motivo, portanto não poderá ter certeza se esse tempo é realmente necessário. O que o gráfico de chamadas diz a você? Cada arco informa que alguma função A estava no processo de chamar alguma função B por uma fração do tempo. Mesmo que A possua apenas uma linha de código chamada B, essa linha fornece apenas uma pequena parte do motivo. Se você tiver sorte o suficiente, talvez essa linha tenha um motivo insuficiente. Normalmente, você precisa ver várias linhas simultâneas para encontrar um motivo ruim, se houver. Se A ligar para B em mais de um local, será informado ainda menos.
essa recursão é uma questão complicada e confusa.
Isso ocorre apenas porque o gprof e outros criadores de perfil percebem a necessidade de gerar um gráfico de chamada e, em seguida, atribuem tempos aos nós. Se houver amostras da pilha, o custo de tempo de cada linha de código que aparece nas amostras é um número muito simples - a fração de amostras em que está. Se houver recursão, uma determinada linha poderá aparecer mais de uma vez em uma amostra. Não importa. Suponha que amostras sejam colhidas a cada N ms e a linha apareça em F% delas (isoladamente ou não). Se essa linha não puder demorar (por exemplo, excluindo-a ou ramificando-a), essas amostras desaparecerão e o tempo será reduzido em F%.
que a precisão da medição do tempo (e, portanto, um grande número de amostras) é importante.
Pense nisso por um segundo. Se uma linha de código estiver em três amostras em cinco, se você puder dispará-la como uma lâmpada, isso é aproximadamente 60% menos tempo que seria usado. Agora, você sabe que, se você tiver tirado 5 amostras diferentes, poderá vê-lo apenas 2 vezes ou até 4. Portanto, essa medição de 60% é mais como uma faixa geral de 40% a 80%. Se fosse apenas 40%, você diria que o problema não vale a pena consertar? Então, qual é a precisão do ponto no tempo, quando o que você realmente deseja é encontrar os problemas ? 500 ou 5000 amostras teriam medido o problema com maior precisão, mas não o teriam encontrado com mais precisão.
que a contagem de chamadas de instruções ou funções é útil.
Suponha que você saiba que uma função foi chamada 1000 vezes. Você pode dizer com isso que fração do tempo custa? Você também precisa saber quanto tempo leva para executar, em média, multiplicá-lo pela contagem e dividir pelo tempo total. O tempo médio de chamada pode variar de nanossegundos a segundos, portanto, a contagem por si só não conta muito. Se houver amostras de pilha, o custo de uma rotina ou de qualquer instrução é apenas a fração de amostras em que está. Essa fração de tempo é o que poderia, em princípio, ser salvo em geral, se a rotina ou a declaração pudesse ser feita com rapidez, e é essa a relação mais direta com o desempenho.
que as amostras não precisam ser coletadas quando bloqueadas
As razões para esse mito são duplas: 1) a amostragem por PC não faz sentido quando o programa está aguardando e 2) a preocupação com a precisão do tempo. No entanto, para (1) o programa pode muito bem estar aguardando algo que ele solicitou, como E / S de arquivo, que você precisa saber e quais exemplos de pilha revelam. (Obviamente, você deseja excluir amostras enquanto aguarda a entrada do usuário.) Para (2) se o programa estiver aguardando simplesmente por causa da concorrência com outros processos, isso presumivelmente acontece de maneira bastante aleatória enquanto estiver em execução. Portanto, embora o programa possa demorar mais, isso não terá um grande efeito sobre a estatística que importa, a porcentagem de tempo em que as instruções estão na pilha.
que o "tempo próprio" é importante
O tempo próprio só faz sentido se você estiver medindo no nível da função, não no nível da linha, e acha que precisa de ajuda para discernir se o tempo da função entra na computação puramente local versus nas rotinas chamadas. Ao resumir no nível da linha, uma linha representa o tempo próprio, se estiver no final da pilha, caso contrário, representa o tempo inclusivo. De qualquer forma, o que custa é a porcentagem de amostras de pilha em que está, de modo que a localiza para você em ambos os casos.
que as amostras precisam ser colhidas em alta frequência
Isso vem da ideia de que um problema de desempenho pode ter ação rápida e que as amostras precisam ser frequentes para atingi-lo. Mas, se o problema estiver custando 20%, digamos, de um tempo total de execução de 10 segundos (ou o que seja), cada amostra nesse tempo total terá 20% de chance de atingi-lo, não importa se o problema ocorrer em uma única peça como essa
.....XXXXXXXX...........................
.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^
(20 amostras, 4 ocorrências)ou em várias partes pequenas como esta
X...X...X.X..X.........X.....X....X.....
.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^
(20 amostras, 3 ocorrências)De qualquer forma, o número de ocorrências será em média de 1 em 5, não importa quantas amostras sejam coletadas, ou Quão poucos. (Média = 20 * 0,2 = 4. Desvio padrão = +/- sqrt (20 * 0,2 * 0,8) = 1,8.)
que você está tentando encontrar o gargalo
como se houvesse apenas um. Considere a seguinte linha do tempo de execução:
vxvWvzvWvxvWvYvWvxvWv.vWvxvWvYvW
Consiste em um trabalho útil real, representado por
.
. Existem problemas de desempenho quevWxYz
levam 1/2, 1/4, 1/8, 1/16, 1/32 do tempo, respectivamente. A amostragem encontrav
facilmente. Ele é removido, deixandoxWzWxWYWxW.WxWYW
Agora o programa leva metade do tempo para ser executado, e agora
W
leva metade do tempo e é encontrado com facilidade. Ele é removido, deixandoxzxYx.xY
Esse processo continua, cada vez que você remove o maior problema de desempenho, em porcentagem, até que nada seja removido. Agora, a única coisa executada é a
.
que é executada em 1/32 do tempo usado pelo programa original. Este é o efeito de ampliação, pelo qual remover qualquer problema aumenta o restante, em porcentagem, porque o denominador é reduzido.Outro ponto crucial é que todos os problemas devem ser encontrados - sem nenhum dos 5. Qualquer problema não encontrado e corrigido reduz severamente a taxa de aceleração final. Apenas encontrar alguns, mas não todos, não é "bom o suficiente".
ADICIONADO: Gostaria apenas de salientar uma das razões pelas quais o gprof é popular - está sendo ensinado, provavelmente porque é gratuito, fácil de ensinar e já existe há muito tempo. Uma rápida pesquisa no Google localiza algumas instituições acadêmicas que ensinam (ou parecem):
** Com exceção de outras maneiras de solicitar que o trabalho seja feito, isso não deixa rastro, indicando o porquê , como a postagem de mensagens.
fonte
Como não vi aqui nada sobre o
perf
que é uma ferramenta relativamente nova para criar um perfil dos aplicativos do kernel e do usuário no Linux, decidi adicionar essas informações.Primeiro de tudo - este é um tutorial sobre criação de perfil do Linux com
perf
Você pode usar
perf
se o seu Kernel Linux for maior que 2.6.32 ouoprofile
se for mais antigo. Ambos os programas não exigem que você instrumente seu programa (comogprof
exige). No entanto, para obter o gráfico de chamadas corretamente,perf
você precisa criar seu programa-fno-omit-frame-pointer
. Por exemplo:g++ -fno-omit-frame-pointer -O2 main.cpp
.Você pode ver a análise "ao vivo" do seu aplicativo com
perf top
:Ou você pode gravar dados de desempenho de um aplicativo em execução e analisá-los depois:
1) Para registrar dados de desempenho:
ou para gravar por 10 segundos:
ou gravar com gráfico de chamadas ()
2) Analisar os dados gravados
Ou você pode gravar dados de desempenho de um aplicativo e analisá-los depois disso, iniciando o aplicativo dessa maneira e esperando que ele saia:
Este é um exemplo de criação de perfil de um programa de teste
O programa de teste está no arquivo main.cpp (colocarei main.cpp na parte inferior da mensagem):
Eu compilo desta maneira:
Eu uso
libmalloc_minimial.so
desde que ele é compilado-fno-omit-frame-pointer
enquanto o libc malloc parece ser compilado sem essa opção. Então eu executo meu programa de testeDepois, registro os dados de desempenho de um processo em execução:
Então analiso a carga por módulo:
A carga por função é analisada:
Em seguida, as cadeias de chamadas são analisadas:
Então, neste ponto, você sabe onde seu programa gasta tempo.
E este é main.cpp para o teste:
fonte
f1
estava chamandodelete
. 40% (aproximadamente) do tempoprocess_request
estava ligandodelete
. Boa parte do restante foi gasta emnew
. As medições são difíceis, mas os pontos ativos são identificados.stackshot
? É isso quepstack
produz?As in my answer, you run it under a debugger and hit ^C at a random time and capture the stack trace
. 1) Acho que sua técnica não é útil quando você precisa analisar problemas de desempenho para um programa em execução no servidor do seu cliente. 2) Não tenho certeza de como você aplica essa técnica para obter informações de um programa com muitos threads que lidam com solicitações diferentes. Quero dizer, quando a imagem geral é bastante complicada.the problem is outside your code
, pode? Como você pode precisar de algumas informações para apoiar seu argumento. Nessa situação, em algum momento você pode precisar criar um perfil do seu aplicativo. Você não pode simplesmente pedir ao seu cliente para iniciar o gdb, pressionar ^ C e obter pilhas de chamadas. Esse foi o meu ponto. Este é um exemplo spielwiese.fontein.de/2012/01/22/… . Eu tive esse problema e a criação de perfil ajudou muito.Experimente o OProfile . É uma ferramenta muito melhor para criar um perfil do seu código. Eu também sugeriria o Intel VTune .
As duas ferramentas acima podem reduzir o tempo gasto em uma linha de código específica, anotar seu código, mostrar montagem e quanta instrução específica leva. Além da métrica de tempo, você também pode consultar contadores específicos, como hits de cache, etc.
Ao contrário do gprof, você pode criar um perfil de qualquer processo / binário em execução no seu sistema usando um dos dois.
fonte
As ferramentas de desempenho do Google incluem um criador de perfil simples de usar. A CPU e o criador de perfil de heap estão disponíveis.
fonte
Dê uma olhada no Sysprof .
Sua distribuição já pode ter.
fonte
http://lttng.org/ se você deseja um rastreador de alto desempenho
fonte