Fortran: najlepszy sposób na czasowe sekcje kodu?


15

Czasami podczas optymalizacji kodu wymagane jest odmierzanie czasu niektórych fragmentów kodu, korzystam z poniższych od lat, ale zastanawiałem się, czy istnieje prostszy / lepszy sposób na zrobienie tego?

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)

Odpowiedzi:


11

Można to zrobić na kilka innych sposobów, z zaletami i wadami:

  • MPI_WTIME : To jest zegar ścienny o wysokiej rozdzielczości. Jest to prawdopodobnie najbardziej „zaufana” opcja; to po prostu działa. Minusem jest to, że jeśli twój program jeszcze nie używa MPI, będziesz musiał go owinąć (co nie jest trudne).
  • Użyj fortranu (jak masz): jest to prawdopodobnie najłatwiejszy i ogólnie wystarczający, ale może nie działać tak dobrze na dziwnej architekturze lub przy równoległych zadaniach. Trwa dyskusja na temat tego przepełnienia stosu
  • Zawiń wywołanie C: Fortran i C są kompatybilne z obiektami, więc łatwo jest napisać opakowanie wokół wywołań C. Kod, z którym pracuję, używa getrusage, co może być dziwnym wyborem. Istnieje wiele dyskusji na ten temat na temat przepełnienia stosu.

Moją osobistą rekomendacją byłoby MPI_WTIME, ponieważ wiesz, że będzie działać dobrze wszędzie tam, gdzie jest MPI. Oto przykład z szybkiego wyszukiwania:

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

  ! code to be timed

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

4

Jeśli używasz kompilatora GNU, sprawdź gprof .

Krótko mówiąc, dodasz flagę -g do swojego kompilatora, w ten sposób:

g77 -g -pg -0 myprogram myprogram.F

Następnie uruchom dane wyjściowe, a plik o nazwie gmon.out pojawi się w twoim katalogu. Wtedy zadzwoń

gprof --line myprogram gmon.out

To da profil czasowy procesora linia po linii.


Dzięki za odpowiedź Muszę tylko wyjaśnić, że prosiłem o programowe rozwiązanie. Profiler jest świetny, ale to więcej niż to, o co prosiłem.
Oscylacja Isopycnal

3
flaga jest -pg, -gjest dla symboli debugowania (również interesujące, ale nie wymagane)
RSFalcon7 11.04.13

Słyszałem w wielu miejscach, że czasy podane przez gprof niekoniecznie są dokładne, takie jak yosefk.com/blog/… , stackoverflow.com/questions/1777556/alternatives-to-gprof/... (i różne inne odpowiedzi Mike Dunlavey na przepełnienie stosu). Narzędzia takie jak gprof i kcachegrind są nadal przydatne, ponieważ liczba wywołań funkcji jest nadal poprawna i dostarczają danych dotyczących czasu, ale nie traktowałbym tego jako ewangelii. DOE ma do tego kilka narzędzi, ale nie wiem, czy są lepsze niż wstawianie timerów.
Geoff Oxberry

1
Poważnie, @IsopycnalOscillation próbuje użyć profilera. Jest to coś nowego do nauczenia się, ale na dłuższą metę pomoże ci ogromnie (i wyczyści kod!).
tmarthal 11.04.13

dzięki @tmarthal Użyłem już profilerów i na pewno będę używał jednego do następnego projektu - całkowicie zgadzam się z tym, co powiedziałeś.
Oscylacja Isopycnal

2

Jak wspomniano w icurays1, najlepsze jest profilowanie. Możesz także nieco uprościć powyższe ...

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

gdzie moduł utils zawiera ...

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

Jeśli masz wiele takich sekcji, przekaż ciąg, np. „Id_sekcji” in toc, aby wypisał identyfikator / nazwę wraz z timingiem.


Sugerowałbym nie tworzenie t1i t2globalne, ale raczej przekazanie t1jako parametru do obu funkcji, aby pozwolić na wiele timerów. Możesz także zwrócić czas, nie drukować niczego.
Pedro
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.