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.

  1. laquelle est la plus précise, ou sont-elles semblables?
  2. est-ce que l'un d'eux compte les erreurs de cache (ou et l'autre pas, ou faire l'un d'eux?
  3. 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

    1. Est plus facile à utiliser, vous n'avez pas besoin des appels d'initialisation
    2. Direct temps dans une différence
    3. devrait aussi être spécifique au compilateur, mais il n'y a aucun moyen de voir la précision. (la norme est millisecondes)
    4. est la somme du temps du fil. I. e. non recommandé pour les pistes parallèles.
  • system_clock

    1. nécessite une pré-initialisation.
    2. après-processus, sous forme de division. (petite chose, mais néanmoins une différence)
    3. 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
    4. est enclin à rencontrer wraparounds, c'est à dire si c1 > c2, en raison de count_max
    5. 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...

24
demandé sur zeroth 2011-07-29 23:44:50

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.

15
répondu M. S. B. 2011-07-29 23:57:12

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.

4
répondu tim18 2015-07-30 17:13:18

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)
3
répondu Karl Yngve Lervåg 2014-02-27 13:13:19

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)
0
répondu bdforbes 2014-02-17 05:17:26