Perf é uma das mais recentes tecnologias do sistema operacional Linux para a coleta e análise de dados de performance, possibilitando a coleta de inúmeros dados de performance que dificilmente seriam coletados de alguma outra maneira no Linux.
A coleta é feita de uma forma simples e adaptável, precisando de alguns poucos comandos para alcançar o resultado desejável, e sua utilização depende de poucos pré-requisitos - basicamente a instalação da ferramenta e permissão de superusuário para a sua execução.
Este artigo visa introduzir a ferramenta Perf a usuários que tenham necessidade de coletar dados de perfomance de aplicações, acerca da utilização do processador e da memória, tais como frequência de acerto e erro de cache, tempos de execução, tempos de acesso ao Translation Lookaside Buffer, entre outros.
Para tanto, é feita uma pequena introdução à ferramenta, detalhando alguns casos de uso, com um exemplo para cada um dos principais subcomandos, seguida por uma seção sobre a instalação da ferramenta, e finalizando com exemplos de coleta de eventos específicos.
Profilling é uma técnica utilizada para coletar informações de um sistema com o objetivo de entender o seu comportamento. É muito utilizada na análise de performance, uma vez que possibilita a avaliação dos tempos de execução de cada instrução, de funções ou de um grupo delas.
A técnica de Profilling também é muito utilizada por desenvolvedores de software, com o objetivo de encontrar comportamentos anormais. Além do mais, é uma técnica útil para entender o fluxo de execução de uma aplicação, principalmente quando não se dispõe de seu código fonte.
1.2 Princípio de Funcionamento: Contadores de performance
A grande mágica por trás do Perf está em algumas características dos processadores, que são capazes de capturar tudo o que acontece no seu interior e armazenar essas informações em registradores denominados "contadores de performance", ou como usualmente denominado em inglês, "performance counters".
Os contadores de performance apareceram com os primeiros processadores Pentium, e hoje estão amplamente disseminados nas principais linhas de processadores do mercado. Observa-se ainda, contudo, uma grande variação na quantidade destes contadores entre estas diferentes arquiteturas, o que, em última análise, determina a quantidade de eventos em paralelo capazes de serem medidos. Os processadores atuais contém pelo menos 8 contadores performance, que são suficientes para uma utilização moderada de eventos. Para mais informações sobre contadores de performance, consultar o manual de arquitetura do processador, como por exemplo "Intel® 64 and IA-32 Architectures Software Developer Manuals" para a arquitetura x86, ou "PowerPC Operating Environment Architecture" para o processador PPC.
Além dos eventos de hardware, o Perf também consegue capturar informações de tracing em aplicativos, visando obter dados que não podem ser capturados via hardware. Esses eventos são denominados Software Events e podem ser adicionados em qualquer aplicativo que o usuário tenha acesso ao código fonte. O kernel do sistema operacional Linux contém inúmeros destes e são amplamente documentados.
O Perf é uma ferramenta composta por vários comandos, cada comando correspondendo à uma função diferente, contendo seus próprios parâmetros de operação.
Segue uma lista dos principais comandos do Perf:
bench Executa alguns micro-benchmarks para calcular performance
diff Mostra a diferença entre dois software em relação a performance
kmem Ferramenta para analisar a memória em espaço de kernel
kvm Ferramenta para analisar a máquina virtual no KVM
list Lista todos os eventos que podem ser mensurados
lock Analisa todos os eventos de lock
sched Analisa o escalonador de processos
stat Analisa as estatísticas de um processo
timechart Mostra visualmente a linha de tempo de execução de um workload
top Ferramenta para mostrar o que está acontecendo na máquina.
|
Neste artigo, será abordado inicialmente os comandos list, stat, top e timechart.
Atualmente o Perf está disponível nos repositórios das distribuições de Linux mais comuns, como por exemplo Fedora, Ubuntu, Suse, etc. Para instalá-lo, basta ir até o repositório de versão para a respectiva distribuição e escolher instalá-lo. Caso, ainda assim, seja necessário instalar manualmente o Perf para um novo kernel, basta executar os seguintes comandos (assumindo que o novo kernel já esta instalado):
wget <latest-kernel>.tar.bz2
tar xjf <latest-kernel>-tar.bz2
cd <latest-kernel>/tools/perf
make
make install
|
A ferramenta Perf oferece a possibilidade de listagem de eventos de hardware (diretamente preenchidos no registradores) como os eventos de software, e, em ambos os casos, a sintaxe é a mesma.
Para selecionar eventos específicos, basta utilizar o parâmetro "-e <nome do evento>" no comando Perf. dentre os quais:
2.2.1. Exemplos de eventos de hardware
cpu-cycles Quantidade de ciclos que a CPU utilizou para tal workload
cache-misses Quantidade de dados que não estavam no cache
branch-misses Quantidade de erros no branch predictor
L1-dcache-loads Quantidade de dados lidos do cache nível 1
LLC-loads Quantidade de dados lidos do cache mais longe (Last Level Cache)
dTLB-stores Quantidade de dados gravados na TLB (Translate Lookaside Buffer)
iTLB-loads Quantidade de instruções foram lidas da TLB
|
2.2.1. Exemplos de eventos de software
skb:kfree_skb Quantidade de vezes que o a função free_skb foi chamada
kvm:kvm_hypercall Quantidade de vezes que houve uma chamada para o KVM
power:cpu_idle Quantidade de vezes que o processador entra em idle
syscalls:<syscall> Quantidade de vezes que uma chamada de sistema é executada
|
O comando stat é, dentre todos, o mais fácil e prático de ser utilizado. Para utilizá-lo, basta executar perf stat <comando a ser executado>. Como resultado, a ferramenta exibirá uma coleção geral de todos os contadores de performance disponíveis – tempo de execução, quantidade de instruções executadas, falhas de páginas e etc, avaliados ao longo da execução do comando fornecido.
Tomamos, como exemplo, a avaliação dos contadores ao longo da execução do comando sleep 1, que simplesmente coloca a shell em espera durante 1 segundo. Note que é possível verificar que o processo demora 1.001 segundos para ser executado, isto é, ele dorme por 1 segundo, e tem um overhead de 0,001 segundos.
[breno@cafe ~]$ perf stat sleep 1
Performance counter stats for 'sleep 1':
0.829030 task-clock-msecs # 0.001 CPUs
2 context-switches # 0.002 M/sec
0 CPU-migrations # 0.000 M/sec
137 page-faults # 0.165 M/sec
973923 cycles # 1174.774 M/sec
590525 instructions # 0.606 IPC
115015 branches # 138.734 M/sec
6037 branch-misses # 5.249 %
9545 cache-references # 11.513 M/sec
2655 cache-misses # 3.203 M/sec
1.001547315 seconds time elapsed
|
Observe que acima são listados os eventos padrão. Caso deseje restringir a amostragem a algum evento específico, basta utilizar-se da opção -e, tal como no exemplo abaixo, no qual apenas o contador do evento L1-dcache-loads é selecionado.
[breno@cafe ~]$ perf stat -e L1-dcache-loads sleep 1
Performance counter stats for 'sleep 1':
179694 L1-dcache-loads
1.001295744 seconds time elapsed
|
Adicionalmente, pode-se especificar a amostragem de mais de um evento. Para isso, a ferramenta perf acomoda a especificação de múltiplas instâncias do parâmetro -e, como pode ser visto abaixo:
[breno@cafe ~]$ perf stat -e L1-dcache-loads -e page-faults sleep 1
|
Este comando é responsável por mostrar as chamadas que estão sendo executadas no computador em um dado instante, ou seja, o que o processador está executando, em termos de funções de bibliotecas e kernel.
Além disso, é possível avaliar a quantidade de interrupções por segundo que o computador está recebendo, e como também a percentagem do tempo que o processador está executando funções em espaço de kernel.
No exemplo abaixo, é possível notar que o computador está 7,4% do tempo sem nada para executar (na função intel_idle()). É possível observar também que boa parte do tempo de processamento é gasto no re-escalonamento de outros processos, como também executando operações de string.
Figura 1.
O timechart é um comando que mostra, de maneira gráfica, a utilização de processos vs processadores na linha do tempo, e o que cada processo está executando. Isso ajuda a entender como e quando os processos estão sendo escalonados, bem como seu comportamento ao longo do tempo.
Um dos aspectos mais observados é a utilização (ocupação) geral de cada CPU, diretamente relacionada com o grau de paralelismo das tarefas em execução, bem como o consumo de energia.
Através do timechart, também é possível observar dependências entre processos, e tempo de espera em entrada/saída, o que auxilia na identificação de potenciais gargalos, e na potencial remoção dos mesmos.
Figura 2.
Neste artigo foi dada uma breve introdução à ferramenta Perf, abortando os casos mais comuns de uso, a sua instalação e utilização. Para mais informações, consulte as referências.
Unofficial Linux Perf Events Performance counters
Intel® 64 and IA-32 Architectures Software Developer Manuals
PowerPC Architecture Book, Version 2.02
