
Meu PC tem dois processadores e sei que cada um roda a 1,86 GHz.
Quero medir o pulso do clock do(s) processador(es) do meu PC manualmente, e minha ideia é apenas calcular o quociente entre o número de linhas assembler que um programa possui e o tempo que meu computador gasta para executá-lo, então eu tenho o número de instruções de montagem por tempo processado pela CPU (isso é o que eu entendi que é um 'ciclo de clock'). Pensei em fazer da seguinte maneira:
- Eu escrevo um programa C e o converto em código assembly.
- Eu faço:
$gcc -S my_program.c
, que diz ao compilador gcc para fazer todo o processo de compilação, exceto a última etapa: transformar my_program.c em um objeto binário. Assim, tenho um arquivo chamado my_program.s que contém a fonte do meu programa C traduzida em código assembler. Conto as linhas que meu programa possui (vamos chamar esse número de N). Eu fiz:
$ nl -l my_program.s | tail -n 1
e obtive o seguinte:1000015 .section .note.GNU-stack,"",@progbits
Quer dizer, o programa tem um milhão de linhas de código.
- Eu faço:
$gcc my_program.c
para que eu possa executá-lo. Eu faço:
$time ./a.out
("a.out" é o nome do objeto binário de meu_programa.c) para obter o tempo (vamos chamá-lo de T) gasto para executar o programa e obtenho:real 0m0.059s user 0m0.000s sys 0m0.004s
Supõe-se que o tempo T que procuro seja o primeiro representado na lista: o "real", pois os demais referem-se a outros recursos que estão rodando no meu sistema no mesmo momento em que executo ./a.out
.
Então eu tenho N=1000015 linhas e T=0,059 segundos. Se eu realizar a divisão N/T obtenho que a frequência está próxima de 17 MHz, o que obviamente não é correto.
Aí pensei que talvez o fato de existirem outros programas rodando no meu computador e consumindo recursos de hardware (sem ir mais longe, o próprio sistema operacional) faz com que o processador "divida" seu "poder de processamento" e faça com que o pulso do clock vá mais lento, mas não tenho certeza.
Mas pensei que, se isso estiver certo, eu também deveria encontrar a porcentagem de recursos da CPU (ou memória) que meu programa consome, porque então eu poderia realmente aspirar a obter um resultado (bem) aproximado sobre a velocidade real da minha CPU.
E isso me leva à questão de como descobrir o “valor de consumo de recursos” do meu programa. Pensei no $ top
comando, mas ele é imediatamente descartado devido ao pouco tempo que meu programa leva para ser executado (0,059 segundos); não é possível distinguir à primeira vista qualquer pico de uso de memória durante esse curto espaço de tempo.
Então, o que você pensa sobre isso? Ou o que você me recomenda fazer? Eu sei que existem programas que fazem esse trabalho que tento fazer, mas prefiro fazê-lo usando o bash bruto porque estou interessado em fazê-lo da maneira mais "universal" possível (parece mais confiável).
Responder1
Isso não vai funcionar. O número de ciclos de clock que cada instrução leva para ser executada (eles levam alguns, não apenas um) depende muito da combinação exata de instruções que a cercam e varia de acordo com o modelo exato da CPU. Você também recebe interrupções e o kernel e outras tarefas têm instruções executadas misturadas com as suas. Além disso, a frequência muda dinamicamente em resposta à carga e à temperatura.
CPUs modernas possuem registros específicos de modelo que contam o número exato de ciclos de clock. Você pode ler isso e, usando um cronômetro de alta resolução, lê-lo novamente um período fixo depois e comparar os dois para descobrir qual foi a frequência (média) nesse período.