Criação de perfis (programação de computador) - Profiling (computer programming)

Em engenharia de software , o perfil ("perfil de programa", "perfil de software") é uma forma de análise dinâmica de programa que mede, por exemplo, o espaço (memória) ou complexidade de tempo de um programa , o uso de instruções específicas ou a frequência e duração das chamadas de função. Mais comumente, as informações de perfil servem para auxiliar na otimização do programa e, mais especificamente, na engenharia de desempenho .

A criação de perfil é obtida instrumentando o código-fonte do programa ou sua forma binária executável usando uma ferramenta chamada profiler (ou criador de perfil de código ). Os criadores de perfil podem usar várias técnicas diferentes, como métodos baseados em eventos, estatísticos, instrumentados e de simulação.

Reunindo eventos do programa

Os criadores de perfil usam uma ampla variedade de técnicas para coletar dados, incluindo interrupções de hardware , instrumentação de código , simulação de conjunto de instruções , ganchos de sistema operacional e contadores de desempenho .

Uso de profilers

Saída gráfica do criador de perfil do CodeAnalyst .

As ferramentas de análise do programa são extremamente importantes para compreender o comportamento do programa. Os arquitetos de computador precisam dessas ferramentas para avaliar o desempenho dos programas em novas arquiteturas . Os criadores de software precisam de ferramentas para analisar seus programas e identificar seções críticas do código. Os escritores de compiladores costumam usar essas ferramentas para descobrir como está o desempenho de seu agendamento de instruções ou algoritmo de previsão de ramificação ...

-  ATOM, PLDI , '94

A saída de um criador de perfil pode ser:

  • Um resumo estatístico dos eventos observados (um perfil )
As informações de perfil de resumo geralmente são mostradas com anotações nas instruções do código-fonte onde os eventos ocorrem, de modo que o tamanho dos dados de medição é linear ao tamanho do código do programa.
/* ------------ source------------------------- count */             
0001             IF X = "A"                     0055
0002                THEN DO                       
0003                  ADD 1 to XCOUNT           0032
0004                ELSE
0005             IF X = "B"                     0055
  • Um fluxo de eventos registrados (um rastreamento )
Para programas sequenciais, um perfil resumido geralmente é suficiente, mas problemas de desempenho em programas paralelos (aguardando mensagens ou problemas de sincronização) geralmente dependem da relação de tempo dos eventos, exigindo, portanto, um rastreamento completo para obter uma compreensão do que está acontecendo.
O tamanho de um traço (completo) é linear ao comprimento do caminho de instrução do programa , tornando-o um tanto impraticável. Um rastreamento pode, portanto, ser iniciado em um ponto em um programa e encerrado em outro ponto para limitar a saída.
  • Uma interação contínua com o hipervisor (monitoramento contínuo ou periódico por meio de exibição na tela, por exemplo)
Isso fornece a oportunidade de ativar ou desativar um rastreamento em qualquer ponto desejado durante a execução, além de visualizar as métricas em andamento sobre o programa (ainda em execução). Ele também oferece a oportunidade de suspender processos assíncronos em pontos críticos para examinar as interações com outros processos paralelos com mais detalhes.

Um profiler pode ser aplicado a um método individual ou na escala de um módulo ou programa, para identificar gargalos de desempenho tornando óbvio o código de longa duração. Um profiler pode ser usado para entender o código do ponto de vista do tempo, com o objetivo de otimizá-lo para lidar com várias condições de tempo de execução ou várias cargas. Os resultados da criação de perfil podem ser ingeridos por um compilador que fornece otimização guiada por perfil . Os resultados da criação de perfil podem ser usados ​​para orientar o projeto e a otimização de um algoritmo individual; o algoritmo de correspondência de curingas de Krauss é um exemplo. Os profilers são integrados a alguns sistemas de gerenciamento de desempenho de aplicativos que agregam dados de criação de perfil para fornecer uma visão sobre as cargas de trabalho de transações em aplicativos distribuídos .

História

Ferramentas de análise de desempenho existiam nas plataformas IBM / 360 e IBM / 370 desde o início dos anos 1970, geralmente baseadas em interrupções de cronômetro que registravam a palavra de status do programa (PSW) em intervalos de cronômetro definidos para detectar "pontos quentes" na execução do código. Este foi um dos primeiros exemplos de amostragem (veja abaixo). No início de 1974 , os simuladores de conjunto de instruções permitiam rastreamento completo e outros recursos de monitoramento de desempenho.

A análise de programa orientada por profiler no Unix remonta a 1973, quando os sistemas Unix incluíam uma ferramenta básica prof, que listava cada função e quanto tempo de execução do programa ela usava. Em 1982 gprofestendeu o conceito para uma análise completa de gráficos de chamadas .

Em 1994, Amitabh Srivastava e Alan Eustace da Digital Equipment Corporation publicou um artigo descrevendo ATOM (Analysis Tools with OM). A plataforma ATOM converte um programa em seu próprio profiler: em tempo de compilação , insere o código no programa a ser analisado. Esse código inserido gera dados de análise. Esta técnica - modificar um programa para se auto-analisar - é conhecida como " instrumentação ".

Em 2004, os gprofartigos e ATOM apareceram na lista dos 50 artigos PLDI mais influentes para o período de 20 anos que terminou em 1999.

Tipos de criador de perfil com base na saída

Perfilador plano

Os criadores de perfil simples calculam os tempos médios das chamadas, a partir das chamadas, e não dividem os tempos das chamadas com base no receptor ou no contexto.

Gerador de perfil de gráfico de chamadas

Os criadores de perfil do gráfico de chamadas mostram os tempos das chamadas e as frequências das funções, e também as cadeias de chamadas envolvidas com base no receptor. Em algumas ferramentas, o contexto completo não é preservado.

Perfilador sensível a entrada

Os criadores de perfil sensíveis à entrada adicionam uma dimensão adicional aos criadores de perfil simples ou de gráfico de chamadas, relacionando as medidas de desempenho aos recursos das cargas de trabalho de entrada, como tamanho de entrada ou valores de entrada. Eles geram gráficos que caracterizam como o desempenho de um aplicativo é dimensionado em função de sua entrada.

Granularidade de dados em tipos de profiler

Os criadores de perfis, que também são programas, analisam os programas alvo coletando informações sobre sua execução. Com base em sua granularidade de dados, em como os criadores de perfil coletam informações, eles são classificados em criadores de perfil baseados em eventos ou estatísticos. Os criadores de perfis interrompem a execução do programa para coletar informações, o que pode resultar em uma resolução limitada nas medições de tempo, que devem ser feitas com cautela. Os criadores de perfil de bloco básico relatam um número de ciclos de clock da máquina dedicados à execução de cada linha de código, ou um tempo baseado na adição dos mesmos; os tempos relatados por bloco básico podem não refletir a diferença entre acertos e erros do cache .

Perfiladores baseados em eventos

As linguagens de programação listadas aqui têm profilers baseados em eventos:

  • Java : a API JVMTI (JVM Tools Interface), anteriormente JVMPI (JVM Profiling Interface), fornece ganchos para profilers, para capturar eventos como chamadas, carregamento de classe, descarregamento, thread entrar em licença.
  • .NET : pode anexar um agente de criação de perfil como um servidor COM ao CLR usando a API de criação de perfil . Como Java, o tempo de execução fornece vários retornos de chamada para o agente, para eventos de trap como método JIT / entrar / sair, criação de objeto, etc. Particularmente poderoso porque o agente de criação de perfil pode reescrever o bytecode do aplicativo de destino de maneiras arbitrárias.
  • Python : Python profiling inclui o módulo de perfil, hotshot (que é baseado em call-graph), e usando a função 'sys.setprofile' para capturar eventos como c_ {call, return, exception}, python_ {call, return, exception}.
  • Ruby : Ruby também usa uma interface semelhante ao Python para criação de perfil. Flat-profiler em profile.rb, module e ruby-prof e uma extensão C estão presentes.

Perfiladores estatísticos

Alguns perfis operam por amostragem . Um gerador de perfil de amostragem investiga a pilha de chamadas do programa de destino em intervalos regulares usando interrupções do sistema operacional . Perfis de amostragem são normalmente menos precisos e específicos, mas permitem que o programa de destino seja executado em velocidade quase total.

Os dados resultantes não são exatos, mas uma aproximação estatística. "A quantidade real de erro é geralmente mais de um período de amostragem. Na verdade, se um valor for n vezes o período de amostragem, o erro esperado é a raiz quadrada de n períodos de amostragem."

Na prática, os criadores de perfil de amostragem podem frequentemente fornecer uma imagem mais precisa da execução do programa de destino do que outras abordagens, pois não são tão intrusivos para o programa de destino e, portanto, não têm tantos efeitos colaterais (como em caches de memória ou instrução pipelines de decodificação). Além disso, como eles não afetam tanto a velocidade de execução, eles podem detectar problemas que, de outra forma, estariam ocultos. Eles também são relativamente imunes à superavaliação do custo de rotinas pequenas, freqüentemente chamadas de loops 'apertados'. Eles podem mostrar a quantidade relativa de tempo gasto no modo de usuário em relação ao modo kernel interrompível, como o processamento de chamadas do sistema .

Ainda assim, o código do kernel para lidar com as interrupções acarreta uma pequena perda de ciclos de CPU, uso de cache desviado e é incapaz de distinguir as várias tarefas que ocorrem no código do kernel ininterrupto (atividade de intervalo de microssegundos).

O hardware dedicado pode ir além disso: ARM Cortex-M3 e alguns processadores MIPS recentes da interface JTAG têm um registro PCSAMPLE, que mostra o contador do programa de uma maneira verdadeiramente indetectável, permitindo a coleta não intrusiva de um perfil plano.

Alguns geradores de perfil estatísticos comumente usados ​​para código Java / gerenciado são SmartBear Software 's AQtime e Microsoft 's CLR Profiler . Esses perfis também suportam perfis de código nativo, juntamente com a Apple Inc. 's Tubarão (OSX), OProfile (Linux), Intel VTune e paralela Amplificador (parte da Intel Parallel Estúdio ), e o Oracle Performance Analyzer , entre outros.

Instrumentação

Essa técnica adiciona efetivamente instruções ao programa de destino para coletar as informações necessárias. Observe que instrumentar um programa pode causar alterações de desempenho e, em alguns casos, levar a resultados imprecisos e / ou heisenbugs . O efeito dependerá de quais informações estão sendo coletadas, do nível de detalhes de tempo relatados e se o perfil de bloco básico é usado em conjunto com a instrumentação. Por exemplo, adicionar código para contar cada chamada de procedimento / rotina provavelmente terá menos efeito do que contar quantas vezes cada instrução é obedecida. Alguns computadores possuem hardware especial para coletar informações; neste caso, o impacto no programa é mínimo.

A instrumentação é a chave para determinar o nível de controle e a quantidade de resolução de tempo disponível para os criadores de perfil.

  • Manual : realizado pelo programador, por exemplo, adicionando instruções para calcular explicitamente os tempos de execução, simplesmente conte eventos ou chamadas para APIs de medição , como o padrão Application Response Measurement .
  • Nível de origem automática : instrumentação adicionada ao código-fonte por uma ferramenta automática de acordo com uma política de instrumentação.
  • Linguagem intermediária : instrumentação adicionada ao assembly ou bytecodes descompilados dando suporte para vários idiomas de origem de nível superior e evitando problemas de reescrita de deslocamento binário (não simbólico).
  • Assistido por compilador
  • Tradução binária : a ferramenta adiciona instrumentação a um executável compilado .
  • Instrumentação em tempo de execução : diretamente antes da execução, o código é instrumentado. A execução do programa é totalmente supervisionada e controlada pela ferramenta.
  • Injeção de tempo de execução: Mais leve do que a instrumentação de tempo de execução. O código é modificado em tempo de execução para ter saltos para funções auxiliares.

Instrumentação de intérprete

  • As opções de depuração do intérprete podem permitir a coleta de métricas de desempenho conforme o intérprete encontra cada instrução de destino. Um bytecode , tabela de controle ou interpretadores JIT são três exemplos que geralmente têm controle completo sobre a execução do código de destino, permitindo oportunidades de coleta de dados extremamente abrangentes.

Hipervisor / Simulador

  • Hipervisor : os dados são coletados executando o programa (geralmente) não modificado em um hipervisor . Exemplo: SIMMON
  • Simulador e hipervisor : Dados coletados interativa e seletivamente executando o programa não modificado em um Simulador de conjunto de instruções .

Veja também

Referências

links externos