Fortran: Kodunuzun bölümlerini ayırmanın en iyi yolu?


15

Bazen kodu optimize ederken kodun belirli bölümlerini zamanlamak için gereklidir, ben yıllardır aşağıdakileri kullanıyorum ama bunu yapmak için daha basit / daha iyi bir yol olup olmadığını merak ediyordum?

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)

Yanıtlar:


11

Bunu yapmanın avantajları ve dezavantajları olan başka birkaç yolu vardır:

  • MPI_WTIME : Bu yüksek çözünürlüklü bir duvar saati. Muhtemelen en `` güvenilir '' seçenektir; sadece işe yarıyor. Dezavantajı, programınız zaten MPI kullanmıyorsa, MPI'yi etrafına sarmanız (zor değildir).
  • Bir fortran intrinsic kullanın (sizin gibi): Bu muhtemelen en kolay ve genellikle yeterlidir, ancak garip bir mimari veya paralel işler için çok iyi çalışmayabilir. Bu Yığın Taşması ile ilgili bir tartışma var
  • Bir C çağrısını sarın: Fortran ve C nesne uyumludur, bu nedenle C çağrılarının etrafına bir sarmalayıcı yazmak yeterince kolaydır. Çalıştığım bir kod garip bir seçim olabilir getrusage kullanır. Bunun Stack Overflow ile ilgili birçok tartışması var .

Kişisel tavsiyem MPI'nin olduğu her yerde iyi çalışacağını bildiğiniz için MPI_WTIME olacaktır. Hızlı aramadan bir örnek :

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

  ! code to be timed

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

4

GNU derleyicisini kullanıyorsanız, gprof'a bakın .

Kısacası, derleyicinize -g bayrağını eklersiniz, şöyle:

g77 -g -pg -0 myprogram myprogram.F

Ardından, çıktıyı çalıştırın ve dizininizde gmon.out adlı bir dosya görünecektir. Sonra ara

gprof --line myprogram gmon.out

Bu, satır satır CPU zaman profilini verecektir.


Cevabınız için teşekkürler, sadece programlı bir çözüm istediğimi açıklığa kavuşturmak zorundayım. Bir profil oluşturucu harika ama istediğimden daha fazlası.
İzopycnal Salınımı

3
bayrağıdır -pg, -gayıklama sembolleri için (aynı zamanda ilginç, ancak gerekli değildir) 'dir
RSFalcon7

Birden fazla yerde gprof tarafından verilen zamanlamaların yosefk.com/blog/… , stackoverflow.com/questions/1777556/alternatives-to-gprof/… (ve diğer çeşitli Mike Dunlavey cevapları) gibi kesin olarak doğru olmadığını duydum. Yığın Taşması). Gprof ve kcachegrind gibi araçlar hala yararlıdır, çünkü işlev çağrılarının sayısı hala doğrudur ve size bazı zamanlama verileri verir, ancak gospel olarak ele almam. DOE'nin bunun için bazı araçları var, ancak zamanlayıcı eklemekten daha iyi olup olmadıklarını bilmiyorum.
Geoff Oxberry

1
Ciddi, @IsopycnalOscillation profiler kullanmaya çalışın. Öğrenmesi yeni bir şeydir, ancak uzun vadede muazzam bir şekilde (ve kodunuzu temizlemeniz!)
tmarthal

thanks @tmarthal Daha önce profiler kullandım ve kesinlikle bir sonraki projem için bir tane kullanacağım - söylediklerine tamamen katılıyorum.
İzopycnal Salınımı

2

İcurays1 tarafından belirtildiği gibi profilleme en iyisidir. Yukarıdakileri de biraz basitleştirebilirsiniz ...

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

utils modülünün bulunduğu ...

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

Bu tür birçok bölümünüz varsa, zamanlama ile birlikte kimliği / adı yazdırması için toc içine bir dize, örneğin "section_id" iletin.


Ben yapma t1ve t2küresel değil , daha ziyade t1birden fazla zamanlayıcı izin için her iki fonksiyon için bir parametre olarak geçmesini öneririm . Ayrıca hiçbir zaman yazdıramaz, zamanı geri döndürebilirsiniz.
Pedro
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.