É possível monitorar um bloco de código e determinar o número de ciclos de clock do processador que o código levou em um processador Armelino e / ou AVR atmel? ou devo monitorar os microssegundos passados antes e depois da execução do código? Nota: Não me preocupo com o tempo real (por exemplo, quantos segundos reais se passaram) tanto quanto em "quantos ciclos de clock esse código requer da CPU"
A solução atual que posso encontrar é do time.c:
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
cablagem.c acrescenta:
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
Por essa conta, eu poderia calcular os estilos de relógio passados monitorando os microssegundos passados e depois passá-los para microsecondsToClockCycles (). Minha pergunta é: existe uma maneira melhor?
Nota: existem bons recursos para o monitoramento de desempenho do AVR. lmgtfy.com e várias pesquisas em fóruns não fornecem nenhum resultado óbvio, além da exploração de temporizadores
obrigado
O que você quer dizer com "monitor"?
Não deve ser difícil contar os ciclos de clock do AVR para pequenos pedaços de código de montagem.
Você também pode definir uma porta antes que o código seja executado e redefini-la posteriormente e monitorá-la com um analisador lógico ou um osziloscópio para obter o tempo.
E você também pode ler a hora em um timer de execução rápida, como você diz.
fonte
Este é um exemplo para o Arduino usando a função clockCyclesPerMicrosecond () para calcular os relógios que passaram. Esse código aguardará 4 segundos e imprimirá o tempo decorrido desde o início do programa. Os valores da esquerda 3 são o tempo total (microssegundos, milissegundos, ciclos totais de clock) e os três à direita são os tempos decorridos:
Resultado:
Tenho certeza de que há uma explicação razoável por que os primeiros loops também tiveram ciclos de relógio decorridos mais curtos do que a maioria e por que todos os outros loops alternam entre dois comprimentos de ciclos de relógio.
Código:
Nota: se você remover o atraso de 4 segundos, começará a ver os efeitos do Serial.print () com muito mais clareza. Observe que aqui são comparadas duas execuções. Eu incluí apenas 4 amostras próximas umas das outras nos respectivos logs.
Execução 1:
Execução 2:
O tempo decorrido aumenta ao longo do tempo total de execução. Após um segundo, os relógios aumentam, em média, de 40k para 44k. Isso acontece consistentemente alguns milissegundos após 1 segundo e os relógios decorridos permanecem em torno de 44k por pelo menos os próximos 10 segundos (eu ainda não o testei mais). É por isso que o monitoramento é útil ou necessário. Talvez a diminuição da eficiência tenha a ver com configuração ou bugs em série? Ou talvez o código não esteja usando a memória corretamente e tenha um vazamento que afeta o desempenho etc.
fonte
Como cada linha de código adicionada à sua fonte terá um impacto no desempenho e poderá alterar as otimizações aplicadas. As alterações devem ser o mínimo necessário para executar a tarefa.
Acabei de encontrar um plug-in do Atmel Studio chamado "Annotated Assembly File Debugger". http://www.atmel.com/webdoc/aafdebugger/pr01.html Parece percorrer a linguagem assembly gerada real enquanto provavelmente tedioso mostrará exatamente o que está acontecendo. Você ainda pode decodificar quantos ciclos são necessários para cada instrução, mas isso fica muito mais próximo do que algumas das outras opções publicadas.
Para aqueles que não sabem na pasta Saída do seu projeto, é um arquivo com uma extensão LSS. Este arquivo contém todo o seu código-fonte original como comentários e abaixo de cada linha está a linguagem de montagem que foi gerada com base nessa linha de código. A geração do arquivo LSS pode ser desativada. Verifique a seguinte configuração.
Propriedades do projeto | Toolchain | Comum AVR / GNU | OutputFiles
Caixa de seleção ".lss (Gerar arquivo lss)
fonte
Você pode usar um dos temporizadores embutidos. Prepare tudo para prescaller = 1 e TCNT = 0 antes do bloco. Em seguida, ative o cronômetro na linha antes do bloco e desative-o na linha após o bloco. O TCNT agora retém o número de ciclos que o bloco levou, menos os ciclos fixos para o código de habilitação e desabilitação.
Observe que o TNCT transbordará após o relógio 65535 girar em um timer de 16 bits. Você pode usar o sinalizador de estouro para duplicar o tempo de execução. Se você ainda precisar de mais tempo, poderá usar um pré-calibrador, mas terá menos resolução.
fonte