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

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, что может быть странным выбором. Есть много дискуссий по этому вопросу о переполнении стека.

Моя личная рекомендация будет 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

Это даст построчное время процессора.

icurays1
источник
Спасибо за ответ, я просто должен уточнить, что я просил программного решения. Профилировщик великолепен, но это больше, чем я просил.
Изопикнальное колебание
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()
...

где модуль 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

Если у вас много таких разделов, то передайте строку, например, «section_id» в toc, чтобы она печатала идентификатор / имя вместе со временем.

Stali
источник
Я бы предложил не делать t1и t2глобальный, а скорее передавать t1в качестве параметра обеим функциям, чтобы учесть несколько таймеров. Вы также можете просто вернуть время, ничего не печатая.
Педро