【发布时间】:2011-07-29 19:44:50
【问题描述】:
在为 FORTRAN 程序计时时,我通常只使用命令 call cpu_time(t)。
然后我偶然发现了call system_clock([count,count_rate,count_max]),它似乎做同样的事情。然而,在一个更困难的庄园。
我对这些的了解来自:Old Intel documentation.
我无法在英特尔的主页上找到它。请参阅下面的标记。
- 哪个更准确,或者它们相似?
- 其中一个是否计算缓存未命中(或其他类型)而另一个不计算,或者其中任何一个?
- 或者唯一的区别是我在下面的标记中标记的东西?
这些是我的问题,下面我提供了一个代码供您查看一些时间和用法。他们向我展示了它们在输出上非常相似,因此在实现上似乎也很相似。
我应该注意,我可能会一直坚持使用cpu_time,而且我真的不需要更精确的时间安排。
在下面的代码中,我尝试比较它们。 (我也尝试过更复杂的东西,但为了保持简洁,不会提供) 所以基本上我的结果是:
-
cpu_time- 更容易使用,不需要初始化调用
- 直接时间差
- 也应该是特定于编译器的,但无法查看精度。 (标准是毫秒)
- 是线程时间的总和。 IE。不建议用于并行运行。
-
system_clock- 需要预初始化。
- 后处理,以分割的形式。 (小事,但还是有区别的)
- 是特定于编译器的。在我的电脑上发现了以下内容:
-
Intel 12.0.4 由于
INTEGER精度,使用计数率为 10000。 - gcc-4.4.5使用1000,不知道如何区分
-
Intel 12.0.4 由于
- 容易遇到环绕,即如果
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
为了完成,我在这里给出我的 Intel 12.0.4 和 gcc-4.4.5 编译器的输出。
-
Intel 12.0.4与-O0system_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与-O0system_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
感谢阅读...
【问题讨论】:
-
在gfortran中使用
INTEGER(8)作为SYSTEM_CLOCK会显着增加count_max,对于其他一些编译器也应该是这样。