Fortran intrinsèque calendrier des routines, ce qui est mieux? processeur de temps ou horloge système
quand je chronomètre un programme FORTRAN, j'utilise habituellement la commande call cpu_time(t)
.
Puis je suis tombé sur call system_clock([count,count_rate,count_max])
ce qui semble faire la même chose. Cependant, dans un manoir plus difficile.
Ma connaissance de ceux-ci vient de: Vieux documentation Intel.
Je ne l'ai pas trouvé sur la page D'accueil D'Intel. Voir mon balisage ci-dessous.
- laquelle est la plus précise, ou sont-elles semblables?
- est-ce que l'un d'eux compte les erreurs de cache (ou et l'autre pas, ou faire l'un d'eux?
- ou est-ce que la seule différence est la chose marquée dans ma marge ci-dessous?
ce sont mes questions, ci-dessous j'ai fourni un code pour que vous voyiez quelques horaires et usages. Ils m'ont montré qu'ils sont très similaires en termes de résultats et semblent donc être similaires en termes de mise en œuvre.
Je note que je vais probablement toujours coller avec cpu_time
, et que je n'ai pas vraiment besoin de plus de précision calendrier.
Dans le code ci-dessous j'ai essayé de les comparer. (j'ai aussi essayé des choses plus élaborées, mais je ne fournirai pas pour garder la brièveté) Donc, fondamentalement, mon résultat est:
cpu_time
- Est plus facile à utiliser, vous n'avez pas besoin des appels d'initialisation
- Direct temps dans une différence
- devrait aussi être spécifique au compilateur, mais il n'y a aucun moyen de voir la précision. (la norme est millisecondes)
- est la somme du temps du fil. I. e. non recommandé pour les pistes parallèles.
system_clock
- nécessite une pré-initialisation.
- après-processus, sous forme de division. (petite chose, mais néanmoins une différence)
- est spécifique au compilateur. Sur mon PC ce qui suit a été trouvé:
- Intel 12.0.4 utilise un taux de comptage de 10000, dû à la
INTEGER
précision. - gcc-4.4.5 utilise 1000, ne sait pas comment cela différencie
- Intel 12.0.4 utilise un taux de comptage de 10000, dû à la
- est enclin à rencontrer wraparounds, c'est à dire si
c1 > c2
, en raison decount_max
- Est temps à partir d'une norme de temps. Ainsi cela donnera le temps réel d'un fil et pas la somme.
Code:
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
pour compléter je donne ici la sortie de mon Intel 12.0.4 et le compilateur 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
Merci d'avoir lu...
4 réponses
ces deux intrinsèques rapportent des types de temps différents. system_clock signale "wall time" ou le temps écoulé. cpu_time indique le temps utilisé par le CPU. Sur une machine multitâche, celles-ci peuvent être très différentes, par exemple, si votre processus partageait le CPU de manière égale avec trois autres processus et recevait donc 25% du CPU et utilisait 10 Secondes cpu, cela prendrait environ 40 secondes de temps réel écoulé ou temps d'horloge murale.
cpu_time () a généralement une résolution d'environ 0.01 seconde sur les CPUs compatibles Intel. Cela signifie qu'un intervalle de temps plus petit peut compter comme temps zéro. La plupart des compilateurs actuels pour linux font que la résolution de system_clock() dépend des types de données des arguments, donc integer(int64) donnera une meilleure résolution que 1 microseconde, en plus de permettre le comptage sur un intervalle de temps significatif. gfortran pour Windows a été modifié récemment (en 2015) afin de rendre system_clock () équivalent pour query_performance appels. ifort Windows, cependant, affiche toujours une résolution d'environ 0.01 pour system_clock, même après que omp_get_wtime a été modifié pour utiliser query_performance. Je ne tiendrais pas compte des commentaires antérieurs sur la mesure de la résolution cpu_time ou system_clock dans les TIC-TAC d'horloge, particulièrement si on peut penser que cela se rapporte à des TIC-TAC de CPU ou de bus de données, comme l'instruction rdtsc pourrait rapporter.
j'ai trouver itime
(voir manuel gfortran) pour être une bonne alternative.system_clock
pour le timing des programmes fortran. Il est très facile à utiliser:
integer, dimension(3) :: time
call itime(time)
print *, 'Hour: ', time(1)
print *, 'Minute:', time(2)
print *, 'Second:', time(3)
je trouve que secnds () est la façon la plus facile d'obtenir du temps d'attente. Son utilisation est presque identique à cpu_time().
real(8)::t1,delta
t1=secnds(0.0)
!Do stuff
delta=seconds(t1)