Eu tenho um programa C que visa ser executado em paralelo em vários processadores. Preciso gravar o tempo de execução (que pode variar de 1 segundo a vários minutos). Procurei respostas, mas todas parecem sugerir o uso da clock()
função, que envolve o cálculo do número de relógios que o programa levou dividido pelo Clocks_per_second
valor.
Não tenho certeza de como o Clocks_per_second
valor é calculado?
Em Java, apenas dedico o tempo atual em milissegundos antes e após a execução.
Existe algo semelhante em C? Eu dei uma olhada, mas não consigo encontrar uma maneira de obter algo melhor do que uma segunda resolução.
Também sei que um criador de perfil seria uma opção, mas estou procurando implementar um cronômetro.
obrigado
c
benchmarking
Roger
fonte
fonte
Respostas:
CLOCKS_PER_SEC
é uma constante que é declarada em<time.h>
. Para obter o tempo de CPU usado por uma tarefa em um aplicativo C, use:Observe que isso retorna a hora como um tipo de ponto flutuante. Isso pode ser mais preciso do que um segundo (por exemplo, você mede 4,52 segundos). A precisão depende da arquitetura; em sistemas modernos, você obtém facilmente 10ms ou menos, mas em máquinas Windows mais antigas (da era Win98), era mais próximo de 60ms.
clock()
é padrão C; funciona "em qualquer lugar". Existem funções específicas do sistema, comogetrusage()
em sistemas similares ao Unix.Java
System.currentTimeMillis()
não mede a mesma coisa. É um "relógio de parede": pode ajudá-lo a medir quanto tempo levou para a execução do programa, mas não informa quanto tempo de CPU foi usado. Em sistemas multitarefa (ou seja, todos eles), estes podem ser amplamente diferentes.fonte
clock()
retorna um tempo em alguma escala interna chamada "relógios" eCLOCKS_PER_SEC
é o número de relógios por segundo, dividindo-o porCLOCKS_PER_SEC
um tempo em segundos. No código acima, o valor é adouble
para que você possa escalá-lo à vontade.CLOCKS_PER_SEC
é umlong int
com o valor1000000
, dando tempo em microssegundos quando não dividido; não ciclos de clock da CPU. Portanto, ele não precisa levar em consideração a frequência dinâmica, pois o relógio aqui está em microssegundos (talvez ciclos de clock para uma CPU de 1 MHz?) Eu fiz um pequeno programa em C imprimindo esse valor e era 1000000 no meu laptop i7-2640M, com frequência dinâmica, permitindo 800 MHz a 2,8 GHz, mesmo usando o Turbo Boost para atingir 3,5 GHz.Se você estiver usando o shell Unix para execução, poderá usar o comando time.
fazendo
assumindo a.out como o executável lhe dará o tempo necessário para executar este
fonte
perf stat ./a.out
para obter contadores de desempenho de HW para falhas de cache e desvios de agência e IPC.Em baunilha C simples:
fonte
Você deseja funcionalmente isso:
Observe que isso mede em microssegundos, não apenas em segundos.
fonte
gettimeofday
está obsoleto e não é recomendado para novo código. Sua página do manual POSIX recomenda o clock_gettime , que permite solicitarCLOCK_MONOTONIC
que não seja afetado pelas alterações no relógio do sistema e, portanto, é melhor como um intervalo de tempo. (Veja a resposta de JohnSll ). Nos sistemas Linux modernos, por exemplo, gettimeofday é basicamente um invólucro para clock_gettime que converte nanossegundos em microssegundos.A maioria dos programas simples possui tempo de computação em milissegundos. Então, suponho, você achará isso útil.
Se você deseja calcular o tempo de execução de todo o programa e você estiver em um sistema Unix, execute o programa usando o comando time como este
time ./a.out
fonte
Muitas respostas foram sugeridas
clock()
e depois aCLOCKS_PER_SEC
partir detime.h
. Provavelmente, essa é uma péssima idéia, porque é isso que meu/bits/time.h
arquivo diz:Portanto,
CLOCKS_PER_SEC
pode ser definido como 1000000, dependendo de quais opções você usa para compilar e, portanto, não parece ser uma boa solução.fonte
CLOCK_PER_SEC==1000000
, mas, ao mesmo tempo, todos usam precisão de 1 µs para a implementação do clock (); a propósito, ele tem a propriedade de reduzir os problemas de compartilhamento. Se você deseja medir eventos potencialmente muito rápidos, digamos abaixo de 1 ms, primeiro você deve se preocupar com a precisão (ou resolução) da função clock (), que é necessariamente mais grossa do que 1 µs no Posix, mas geralmente é muito mais grossa; a solução usual é executar o teste várias vezes; a pergunta feita não parecia exigir, no entanto.clock()
, se você dividir esse valor comCLOCK_PER_SEC
garantia de tempo em segundos que a CPU levou. A responsabilidade de medir a velocidade real do relógio é responsabilidade daclock()
função, não sua.A resposta de Thomas Pornin como macros:
Use-o assim:
Resultado:
fonte
Você deve levar em consideração que medir o tempo que levou a execução de um programa depende muito da carga que a máquina possui naquele momento específico.
Sabendo que, a maneira de obter o tempo atual em C pode ser alcançada de diferentes maneiras, é mais fácil:
Espero que ajude.
Saudações!
fonte
(Todas as respostas aqui estão ausentes, se o administrador do sistema alterar a hora do sistema ou se o fuso horário tiver horários diferentes de inverno e de verão. Portanto ...)
No uso do linux:
clock_gettime(CLOCK_MONOTONIC_RAW, &time_variable);
não será afetado se o administrador do sistema alterar a hora ou se você mora em um país com horário de inverno diferente do horário de verão etc.man clock_gettime
afirma:fonte
(end.tv_nsec - begin.tv_nsec) / 1000000000.0
resultado não seria0
sempre?double
literal dispara int oulong
àdouble
conversão antes da divisão. É claro que você pode usar o número inteiro e imprimir atv_sec
peça e, em seguida, a parte fracionária com zero como%ld.%09ld
, mas converter para o dobro é fácil e 53 bits de precisão geralmente são suficientes para tempos de referência.timespec_subtract
tipotimeval_subtract
sugerido no manual da glibc : gnu.org/software/libc/manual/html_node/Elapsed-Time.html )O ANSI C especifica apenas as funções de segunda hora de precisão. No entanto, se você estiver executando em um ambiente POSIX, poderá usar a função gettimeofday () que fornece microssegundos de resolução de tempo passado desde a época do UNIX.
Como uma observação lateral, eu não recomendaria o uso de clock (), pois ele é mal implementado em muitos sistemas (se não todos?) E não é preciso, além do fato de que se refere apenas ao tempo que o seu programa passou na CPU e não o tempo de vida total do programa, que, de acordo com sua pergunta, é o que suponho que você gostaria de medir.
fonte
Todas as soluções não estão funcionando no meu sistema.
Eu posso usar
fonte
time_t
valores como um dobro. Como ostime_t
valores são precisos apenas por um segundo, é de valor limitado a impressão do tempo gasto pelos programas de execução curta, embora possa ser útil para programas executados por longos períodos.clock_t
s paradifftime
parece funcionar para mim com a precisão de um centésimo de segundo. Isso está no linux x86. Também não consigo subtrairstop
estart
trabalhar.difftime()
clock() / CLOCKS_PER_SEC
, pois espera segundos.fonte
Descobri que o relógio usual (), todo mundo recomenda aqui, por algum motivo se desvia muito de uma corrida para outra, mesmo para código estático sem efeitos colaterais, como desenhar na tela ou ler arquivos. Pode ser porque a CPU altera os modos de consumo de energia, OS dando prioridades diferentes, etc ...
Portanto, a única maneira de obter o mesmo resultado sempre de forma confiável com clock () é executar o código medido em um loop várias vezes (por vários minutos), tomando precauções para impedir que o compilador o otimize: os compiladores modernos podem pré-calcular o código sem efeitos colaterais sendo executados em um loop e mova-o para fora do loop., como, por exemplo, usar entrada aleatória para cada iteração.
Depois que amostras suficientes são coletadas em uma matriz, uma classifica essa matriz e pega o elemento do meio, chamado mediana. A mediana é melhor que a média, porque elimina desvios extremos, como, por exemplo, antivírus que ocupam toda a CPU ou OS fazendo alguma atualização.
Aqui está um utilitário simples para medir o desempenho de execução do código C / C ++, com a média dos valores próximos da mediana: https://github.com/saniv/gauge
Ainda estou procurando uma maneira mais rápida e robusta de medir o código. Provavelmente, pode-se tentar executar o código em condições controladas no bare metal sem nenhum sistema operacional, mas isso dará um resultado irreal, porque, na realidade, o sistema operacional se envolve.
O x86 possui esses contadores de desempenho de hardware, que incluem o número real de instruções executadas, mas são difíceis de acessar sem a ajuda do SO, difíceis de interpretar e têm seus próprios problemas ( http://archive.gamedev.net/archive/reference/articles /article213.html ). Ainda assim, eles podem ser úteis para investigar a natureza do gargalo da garrafa (acesso a dados ou cálculos reais nesses dados).
fonte
performance
) ou muitas dezenas de milissegundos. en.wikipedia.org/wiki/Dynamic_frequency_scaling . E sim, o desempenho médio geralmente é uma boa escolha; o high-end geralmente tem alguns picos de interferência.main
que recebe um argumento e retorna um resultado e não use a otimização do tempo do link. Em seguida, o compilador não pode incorporá-lo no chamador. Só funciona se a função já incluir algum tipo de loop, caso contrário, a sobrecarga de chamada / retenção é muito alta.Alguns podem achar útil um tipo diferente de entrada: recebi esse método de medir o tempo como parte de um curso universitário de programação GPGPU com a NVidia CUDA ( descrição do curso ). Ele combina os métodos vistos nas postagens anteriores, e eu simplesmente a publico porque os requisitos dão credibilidade:
Suponho que você possa se multiplicar, por exemplo,
1.0 / 1000.0
para obter a unidade de medida que atenda às suas necessidades.fonte
clock_gettime
, em vez disso, que permite que vocêCLOCK_MONOTONIC
não seja afetado por alterações no relógio do sistema e, portanto, é melhor como um temporizador de intervalo. Nos sistemas Linux modernos, por exemplo,gettimeofday
é basicamente um invólucroclock_gettime
que converte nanossegundos em microssegundos. (Veja a resposta de JohnSll).timeval_subtract
.Comparação do tempo de execução do tipo de bolha e do tipo de seleção Eu tenho um programa que compara o tempo de execução do tipo de bolha e do tipo de seleção. Para descobrir o tempo de execução de um bloco de código, calcule o tempo antes e depois do bloco,
Código de exemplo:
fonte