포트란 : 코드의 시간 섹션에 가장 적합한 방법은?


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가있는 곳이라면 어디에서나 잘 작동한다는 것을 알기 때문에 개인적 추천은 MPI_WTIME입니다. 빠른 검색 의 는 다음과 같습니다 .

  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

이것은 라인 별 CPU 시간 프로파일을 제공합니다.


답을 보내 주셔서 감사합니다. 프로그래밍 솔루션을 요청하고 있음을 분명히해야합니다. 프로파일 러는 훌륭하지만 내가 요구 한 것 이상입니다.
Isopycnal Oscillation

3
플래그는 -pg, -g디버그 심볼 (흥미, 필수 사항은 아님)입니다
RSFalcon7

여러 곳에서 yosefk.com/blog/… , stackoverflow.com/questions/1777556/alternatives-to-gprof/… 와 같은 gprof가 제공하는 타이밍이 정확하지는 않다고 들었습니다 (및 다양한 다른 Mike Dunlavey 답변 스택 오버플로). 함수 호출 수가 여전히 정확하고 타이밍 데이터를 제공한다는 점에서 gprof 및 kcachegrind와 같은 도구는 여전히 유용하지만 복음으로 취급하지는 않습니다. 교육청에는이를위한 몇 가지 도구가 있지만 타이머를 삽입하는 것보다 더 나은지 모르겠습니다.
Geoff Oxberry

1
@IsopycnalOscillation은 프로파일 러를 사용하려고합니다. 배우는 것은 새로운 것이지만 장기적으로는 엄청나게 도움이 될 것입니다.
tmarthal

덕분에 @tmarthal 감사합니다. 프로파일 러를 사용했으며 다음 프로젝트에 프로파일 러를 사용할 것입니다. 말씀하신 내용에 전적으로 동의합니다.
Isopycnal Oscillation

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

이러한 섹션이 많은 경우 toc에 "section_id"와 같은 문자열을 전달하여 타이밍과 함께 id / name을 인쇄합니다.


여러 타이머를 허용하기 위해 작성 t1t2전역이 아니라 t1두 기능에 매개 변수로 전달하는 것이 좋습니다 . 아무 것도 인쇄하지 않고 시간을 반환 할 수도 있습니다.
Pedro
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.