Фортран: Найкращий спосіб для часових розділів вашого коду?


15

Іноді під час оптимізації коду потрібно проводити час на певні частини коду, я використовую наступні роки, але мені було цікаво, чи існує простіший / кращий спосіб зробити це?

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)

Відповіді:


11

Існує кілька інших способів зробити це з перевагами та недоліками:

  • MPI_WTIME : Це настінні годинники з високою роздільною здатністю. Це, мабуть, найбільш «надійний» варіант; це просто працює. Мінус полягає в тому, що якщо ваша програма ще не використовує MPI, вам доведеться обернути MPI навколо неї (що не важко).
  • Використовуйте внутрішню фортран (як у вас є): Це, мабуть, найпростіший і, як правило, достатній, але може не так добре працювати в чужій архітектурі або для паралельних завдань. Трохи обговорюється цей переповнення стека
  • Встановлення дзвінка на C: Fortran і C сумісні з об'єктами, тому досить просто написати обгортку навколо C-дзвінків. Код, з яким я працюю, використовує getrusage, що може бути незвичайним вибором. Існує багато дискусій про це на Stack Overflow.

Моя особиста рекомендація буде MPI_WTIME, оскільки ви знаєте, що вона буде працювати добре там, де є MPI. Ось приклад швидкого пошуку:

  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, перегляньте gprof .

Якщо коротко, ви додасте прапор -g до свого компілятора, наприклад:

g77 -g -pg -0 myprogram myprogram.F

Потім запустіть висновок, і у вашому каталозі з’явиться файл під назвою gmon.out. Потім, дзвоніть

gprof --line myprogram gmon.out

Це дасть лінійний порядок часу процесора.


Дякую за відповідь, я просто повинен уточнити, що я просив програмне рішення. Профілер великий, але це більше, ніж я просив.
Ізопікальні коливання

3
прапор -pg, -gдля налагодження символів (також цікаво, але не обов'язково)
RSFalcon7

Я чув , в декількох місцях , що таймінги , дані дргоЕ не завжди точні, такі як yosefk.com/blog / ... , stackoverflow.com/questions/1777556/alternatives-to-gprof / ... (і різні інші відповіді Майк Dunlavey на стек переповнення). Такі інструменти, як gprof та kcachegrind, як і раніше корисні, оскільки кількість викликів функцій все ще є правильною, і вони дають вам деякі дані про терміни, але я не ставлюся до цього як до євангелія. У DOE є деякі інструменти для цього, але я не знаю, чи вони краще, ніж вставляти таймери.
Джефф Оксберрі

1
Серйозно, @IsopycnalOscillation спробуйте скористатися профілером. Це щось нове навчитися, але це допоможе вам надзвичайно (і очистити код!) В довгостроковій перспективі.
tmarthal

дякую @tmarthal Я раніше використовував профілі, і я обов'язково буду використовувати його для свого наступного проекту - я повністю згоден з тим, що ви сказали.
Ізопікальні коливання

2

Як зазначає icurays1, найкращим є профілювання. Ви також можете трохи спростити вище ...

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

де модуль утиліт містить ...

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

Якщо у вас є багато таких розділів, тоді передайте рядок, наприклад, "section_id" в toc, щоб він друкував id / ім'я разом із тимчасовою ознакою.


Я хотів би запропонувати не робити t1і t2глобальним, а проходячи в t1якості параметра для обох функцій, щоб для кількох таймерів. Ви також можете просто повернути час, нічого не надрукувавши.
Педро
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.