FORTRANプログラムのタイミングをとるとき、私は通常、コマンドcall cpu_time(t)
を使用します。
そして、同じことをしているように見えるcall system_clock([count,count_rate,count_max])
を偶然見つけました。しかし、より難しい邸宅で。これらについての私の知識は以下から得られます: 古いIntelのドキュメント 。
インテルのホームページでそれを見つけることができませんでした。以下のマークアップを参照してください。
これらは私の質問です。以下に、タイミングと使用法を確認するためのコードを示します。彼らは私にそれらが出力で非常に似ていることを示し、したがって実装でも似ているように見えます。
私はおそらく常にcpu_time
、そして私は本当により正確なタイミングを必要としません。
以下のコードで、それらを比較しようとしました。 (私はより手の込んだことも試みましたが、簡潔さを保つために供給しません)だから基本的に私の結果は次のとおりです:
cpu_time
system_clock
INTEGER
の精度により、カウントレート10000を使用します。c1 > c2
、 のため count_max
コード:
PROGRAM timer
IMPLICIT NONE
REAL :: t1,t2,rate
INTEGER :: c1,c2,cr,cm,i,j,n,s
INTEGER , PARAMETER :: x=20000,y=15000,runs=1000
REAL :: array(x,y),a_diff,diff
! First initialize the system_clock
CALL system_clock(count_rate=cr)
CALL system_clock(count_max=cm)
rate = REAL(cr)
WRITE(*,*) "system_clock rate ",rate
diff = 0.0
a_diff = 0.0
s = 0
DO n = 1 , runs
CALL CPU_TIME(t1)
CALL SYSTEM_CLOCK(c1)
FORALL(i = 1:x,j = 1:y)
array(i,j) = REAL(i)*REAL(j) + 2
END FORALL
CALL CPU_TIME(t2)
CALL SYSTEM_CLOCK(c2)
array(1,1) = array(1,2)
IF ( (c2 - c1)/rate < (t2-t1) ) s = s + 1
diff = (c2 - c1)/rate - (t2-t1) + diff
a_diff = ABS((c2 - c1)/rate - (t2-t1)) + a_diff
END DO
WRITE(*,*) "system_clock : ",(c2 - c1)/rate
WRITE(*,*) "cpu_time : ",(t2-t1)
WRITE(*,*) "sc < ct : ",s,"of",runs
WRITE(*,*) "mean diff : ",diff/runs
WRITE(*,*) "abs mean diff: ",a_diff/runs
END PROGRAM timer
ここでiを完了するには、Intel 12.0.4およびgcc-4.4.5コンパイラからの出力を提供します。
Intel 12.0.4
と-O0
system_clock rate 10000.00
system_clock : 2.389600
cpu_time : 2.384033
sc < ct : 1 of 1000
mean diff : 4.2409324E-03
abs mean diff: 4.2409897E-03
real 42m5.340s
user 41m48.869s
sys 0m12.233s
gcc-4.4.5
と-O0
system_clock rate 1000.0000
system_clock : 1.1849999
cpu_time : 1.1840820
sc < ct : 275 of 1000
mean diff : 2.05709646E-03
abs mean diff: 2.71424348E-03
real 19m45.351s
user 19m42.954s
sys 0m0.348s
読んでくれてありがとう...
これら2つの組み込み関数は、異なるタイプの時間を報告します。 system_clockは「ウォールタイム」または経過時間を報告します。 cpu_timeは、CPUが使用した時間を報告します。マルチタスクマシンでは、これらは非常に異なる可能性があります。たとえば、プロセスが他の3つのプロセスとCPUを同等に共有し、CPUの25%を受け取り、10 cpu秒を使用した場合、実際の経過時間または壁には約40秒かかります。時刻。
cpu_time()は通常、Intel互換CPUでは約0.01秒の解像度です。これは、短い時間間隔はゼロ時間としてカウントされる可能性があることを意味します。 Linuxの最新のコンパイラーは、system_clock()の解像度を引数のデータ型に依存させるため、integer(int64)は1マイクロ秒よりも優れた解像度を提供し、かなりの時間間隔でカウントできるようにします。 Windows用のgfortranは、system_clock()がquery_performance呼び出しと同等になるように最近(2015年中に)変更されました。ただし、ifort Windowsでは、omp_get_wtimeがquery_performanceを使用するように変更された後でも、system_clockの解像度は約0.01のままです。特に、CPUまたはデータバスのティックに関連すると考えられる場合、rdtsc命令などが報告する可能性がある場合は、クロックティックでのcpu_timeまたはsystem_clockの解像度の測定に関する以前のコメントを無視します。
itime
( gfortranマニュアル を参照)がsystem_clock
fortranプログラムのタイミング。使い方はとても簡単です。
integer, dimension(3) :: time
call itime(time)
print *, 'Hour: ', time(1)
print *, 'Minute:', time(2)
print *, 'Second:', time(3)
Seconds()が実時間を取得する最も簡単な方法であることがわかりました。その使用法はcpu_time()とほとんど同じです。
real(8)::t1,delta
t1=secnds(0.0)
!Do stuff
delta=seconds(t1)