Fortran: melhor maneira de cronometrar seções do seu código?


15

Às vezes, ao otimizar o código, é necessário cronometrar determinadas partes do código, eu venho usando o seguinte há anos, mas fiquei imaginando se existe uma maneira melhor / mais simples de fazer isso?

call system_clock(count_rate=clock_rate) !Find the time rate
call system_clock(count=clock_start)     !Start Timer

call do_something_subroutine             !This is what gets timed

call system_clock(count=clock_stop)      ! Stop Timer

e_time = real(clock_stop-clock_start)/real(clock_rate)

Respostas:


11

Existem algumas outras maneiras de fazer isso, com vantagens e desvantagens:

  • MPI_WTIME : Este é um relógio de parede de alta resolução. É provavelmente a opção mais `confiável '; simplesmente funciona. A desvantagem é que, se o seu programa ainda não usa MPI, você terá que envolvê-lo (o que não é difícil).
  • Use um fortran intrínseco (como você tem): provavelmente é o mais fácil e geralmente suficiente, mas pode não funcionar tão bem em uma arquitetura estranha ou em trabalhos paralelos. Há um pouco de discussão sobre esse estouro de pilha
  • Finalizar uma chamada em C: Fortran e C são compatíveis com objetos, portanto é fácil escrever um wrapper em torno de chamadas em C. Um código com o qual trabalho usa getrusage, que pode ser uma escolha estranha. Há muitas discussões sobre isso no Stack Overflow.

Minha recomendação pessoal seria MPI_WTIME, como você sabe, funcionará bem onde houver MPI. Aqui está um exemplo de uma pesquisa rápida:

  include 'mpif.h'
  DOUBLE PRECISION :: start, end
  start = MPI_Wtime()

  ! code to be timed

  end   = MPI_Wtime()
  write(*,*) 'That took ',end-start,' seconds'

4

Se você usa o compilador GNU, consulte o gprof .

Em resumo, você adicionará o sinalizador -g ao seu compilador, assim:

g77 -g -pg -0 myprogram myprogram.F

Em seguida, execute a saída e um arquivo chamado gmon.out aparecerá no seu diretório. Em seguida, ligue

gprof --line myprogram gmon.out

Isso fornecerá um perfil de tempo de CPU linha por linha.


Obrigado pela resposta, só preciso esclarecer que estava pedindo uma solução programática. Um criador de perfil é ótimo, mas é mais do que eu estava pedindo.
Oscilação isópica

3
a bandeira é -pg, -gé para símbolos de depuração (também interessante, mas não é obrigatório)
RSFalcon7

Ouvi em vários lugares que os horários fornecidos pelo gprof não são necessariamente precisos, como yosefk.com/blog/… , stackoverflow.com/questions/1777556/alternatives-to-gprof/… (e várias outras respostas de Mike Dunlavey estouro de pilha). Ferramentas como gprof e kcachegrind ainda são úteis, pois o número de chamadas de função ainda está correto e fornecem alguns dados de tempo, mas eu não os trataria como evangelho. O DOE tem algumas ferramentas para isso, mas não sei se elas são melhores do que inserir temporizadores.
precisa saber é o seguinte

1
Sério, @IsopycnalOscillation tenta usar o criador de perfil. É algo novo para aprender, mas irá ajudá-lo tremendamente (e limpar seu código!) A longo prazo.
tmarthal

thanks @tmarthal Eu já usei profilers antes e definitivamente usarei um para o meu próximo projeto - concordo totalmente com o que você disse.
Oscilação isópcica

2

Conforme mencionado pelo icurays1, a criação de perfil é a melhor. Você também pode simplificar um pouco o acima ...

use utils
...
call tic()
   ! Section to be timed
call toc()
...
call tic()
   ! Section to be timed
call toc()
...

onde o módulo utils contém ...

real(8) :: t1,t2
...
subroutine tic()
  implicit none
  call cpu_time(t1)
end subroutine tic

subroutine toc()
  implicit none
  call cpu_time(t2)
  ! if (rank==0) print*,"Time Taken -->", real(t2-t1)
  print*,"Time Taken -->", real(t2-t1)
end subroutine toc

Se você tiver muitas seções, passe uma string, por exemplo, "section_id" em toc para que ela imprima o ID / nome junto com o tempo.


Eu sugeriria não fazer t1e t2global, mas passar t1como parâmetro para ambas as funções, para permitir vários temporizadores. Você também pode simplesmente retornar a hora, não imprimir nada.
Pedro
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.