Fortran: วิธีที่ดีที่สุดในการตั้งเวลาส่วนรหัสของคุณ?


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 รอบตัว (ซึ่งไม่ยาก)
  • ใช้ Fortran ที่แท้จริง (ตามที่คุณมี): นี่อาจเป็นวิธีที่ง่ายที่สุดและเพียงพอโดยทั่วไป แต่อาจใช้งานไม่ได้กับสถาปัตยกรรมที่แปลกประหลาดหรืองานที่ขนานกัน มีการพูดคุยกันเล็กน้อยเกี่ยวกับ Stack Overflow
  • Wrap a C โทร: Fortran และ C เข้ากันได้กับวัตถุดังนั้นจึงง่ายที่จะเขียน wrapper รอบ ๆ การโทร 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 gprof

ในระยะสั้นคุณจะเพิ่มแฟล็ก -g ในคอมไพเลอร์ของคุณเช่น:

g77 -g -pg -0 myprogram myprogram.F

จากนั้นเรียกใช้เอาต์พุตและไฟล์ชื่อ gmon.out จะปรากฏในไดเรกทอรีของคุณ จากนั้นโทร

gprof --line myprogram gmon.out

สิ่งนี้จะให้โปรไฟล์เวลาของ CPU แบบทีละบรรทัด


ขอบคุณสำหรับคำตอบที่ฉันต้องชี้แจงว่าฉันขอวิธีการเขียนโปรแกรม ผู้สร้างโปรไฟล์ยอดเยี่ยม แต่มันเป็นมากกว่าสิ่งที่ฉันขอ
Isopycnal Oscillation

3
ธง-pg, -gเป็นสัญลักษณ์การแก้ปัญหา (ยังเป็นที่น่าสนใจ แต่ไม่จำเป็น)
RSFalcon7

ฉันได้ยินมาหลายที่ว่าการกำหนดเวลาที่กำหนดโดย gprof นั้นไม่ถูกต้องเช่นyosefk.com/blog/… , stackoverflow.com/questions/1777556/alternatives-to-gprof/ ...... (และคำตอบอื่น ๆ ของ Mike Dunlavey บน Stack Overflow) เครื่องมืออย่าง gprof และ kcachegrind ยังคงมีประโยชน์เพราะจำนวนการเรียกฟังก์ชั่นยังคงถูกต้องและพวกมันก็ให้ข้อมูลเวลากับคุณ แต่ฉันจะไม่ถือว่ามันเป็นข่าวประเสริฐ DOE มีเครื่องมือบางอย่างสำหรับสิ่งนี้ แต่ฉันไม่รู้ว่ามันดีกว่าตัวจับเวลาหรือไม่
Geoff Oxberry

1
จริงจัง @IsopycnalOscillation พยายามใช้ profiler มันเป็นสิ่งใหม่ที่จะเรียนรู้ แต่มันจะช่วยคุณอย่างมาก (และทำความสะอาดโค้ดของคุณ!) ในระยะยาว
tmarthal

ขอบคุณ @tmarthal ฉันเคยใช้ profilers มาก่อนและฉันจะใช้มันอย่างแน่นอนสำหรับโครงการต่อไปของฉัน - ฉันเห็นด้วยอย่างยิ่งกับสิ่งที่คุณพูด
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

หากคุณมีหลายส่วนเช่นให้ส่งสตริงเช่น "section_id" ใน toc เพื่อให้พิมพ์ ID / ชื่อพร้อมกับเวลา


ฉันอยากจะแนะนำไม่ให้ทำt1และt2ทั่วโลก แต่แทนที่จะผ่านt1เป็นพารามิเตอร์ให้กับทั้งสองฟังก์ชั่นเพื่ออนุญาตให้มีหลายตัวนับ คุณสามารถคืนเวลาได้โดยไม่ต้องพิมพ์อะไรเลย
Pedro
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.