Fortran: il modo migliore per cronometrare le sezioni del codice?


15

A volte durante l'ottimizzazione del codice è necessario cronometrare alcune parti del codice, sto usando il seguente da anni ma mi chiedevo se esiste un modo più semplice / migliore per farlo?

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)

Risposte:


11

Ci sono alcuni altri modi per farlo, con vantaggi e svantaggi:

  • MPI_WTIME : questo è un orologio da parete ad alta risoluzione. È probabilmente l'opzione più "affidabile"; funziona e basta. Il rovescio della medaglia è che se il tuo programma non usa già MPI, dovrai avvolgerlo attorno (che non è difficile).
  • Usa un fortran intrinseco (come hai fatto): questo è probabilmente il più semplice e generalmente sufficiente, ma potrebbe non funzionare così bene su una strana architettura o per lavori paralleli. C'è un po 'di discussione su questo Stack Overflow
  • Avvolgere una chiamata C: Fortran e C sono compatibili con gli oggetti, quindi è abbastanza facile scrivere un wrapper attorno alle chiamate C. Un codice con cui lavoro usa getrusage, che potrebbe essere una scelta strana. Ci sono molte discussioni di questo su Stack Overflow.

La mia raccomandazione personale sarebbe MPI_WTIME, poiché sai che funzionerà bene ovunque ci sia MPI. Ecco un esempio da una rapida ricerca:

  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 usi il compilatore GNU, controlla gprof .

In breve, aggiungerai il flag -g al tuo compilatore, in questo modo:

g77 -g -pg -0 myprogram myprogram.F

Quindi, esegui l'output e un file chiamato gmon.out apparirà nella tua directory. Quindi chiama

gprof --line myprogram gmon.out

Ciò fornirà un profilo temporale CPU riga per riga.


Grazie per la risposta, devo solo chiarire che stavo chiedendo una soluzione programmatica. Un profiler è fantastico ma è più di quello che stavo chiedendo.
Oscillazione isopycnal

3
la bandiera è -pg, -gè per i simboli di debug (anche interessante, ma non richiesto)
RSFalcon7

Ho sentito in più luoghi che le tempistiche fornite dal gprof non sono necessariamente precisi, come ad esempio yosefk.com/blog/... , stackoverflow.com/questions/1777556/alternatives-to-gprof/... (e varie altre risposte Mike Dunlavey su Stack Overflow). Strumenti come gprof e kcachegrind sono ancora utili, in quanto il numero di chiamate di funzione è ancora corretto e ti danno alcuni dati di temporizzazione, ma non lo tratterei come vangelo. Il DOE ha alcuni strumenti per questo, ma non so se sono migliori dell'inserimento di timer.
Geoff Oxberry,

1
Scherzi a parte, @IsopycnalOscillation tenta di utilizzare il profiler. È qualcosa di nuovo da imparare, ma ti aiuterà moltissimo (e ripulirà il tuo codice!) A lungo termine.
tmarthal,

grazie @tmarthal Ho già usato i profiler e sicuramente ne userò uno per il mio prossimo progetto - sono totalmente d'accordo con quello che hai detto.
Oscillazione isopycnal

2

Come indicato da icurays1, la profilazione è la migliore. Puoi anche semplificare leggermente quanto sopra ...

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

dove contiene il modulo utils ...

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 hai molte di queste sezioni, passa una stringa, ad es. "Section_id" in toc in modo che stampi l'id / nome insieme al tempo.


Suggerirei non fare t1e t2globale, ma piuttosto passare t1come parametro ad entrambe le funzioni, per consentire più timer. Potresti anche restituire l'ora, non stampare nulla.
Pedro,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.