Фортран встроенных процедур синхронизации, что лучше? cpu_time или system_clock - PullRequest
26 голосов
/ 29 июля 2011

При синхронизации программы на Фортране я обычно просто использую команду call cpu_time(t).
Затем я наткнулся на call system_clock([count,count_rate,count_max]), что, похоже, делает то же самое.Однако в более сложной усадьбе.Мои знания об этом получены из: Старая документация Intel .
Я не смог найти ее на домашней странице Intel.См. Мою разметку ниже.

  1. Что является более точным, или они похожи?
  2. Один из них считает ошибки кэша (или другой из видов), а другой нет,или у кого-нибудь из них?
  3. Или единственная разница заключается в том, что в моей разметке ниже помечена вещь?

Это мои вопросы, ниже я предоставил код, который вы сможете увидетьнекоторые сроки и обычаи.Они показали мне, что они очень похожи по выходу и, следовательно, похожи по реализации.
Я должен отметить, что я, вероятно, всегда буду придерживаться cpu_time, и что мне действительно не нужны более точные сроки.

В приведенном ниже коде я попытался сравнить их.(Я также пробовал более сложные вещи, но не буду поставлять, чтобы сохранить краткость) Так что в основном мой результат таков:

  • cpu_time
    1. Прощеиспользуйте, вам не нужны вызовы инициализации
    2. Прямое время в разнице
    3. Также должно зависеть от компилятора, но нет способа увидеть точность.(норма - миллисекунды)
    4. Сумма времени потока.Т.е. не рекомендуется для параллельных прогонов.
  • system_clock
    1. Требуется предварительная инициализация.
    2. Последующая обработка в форме разделения.(маленькая вещь, но тем не менее разница)
    3. Зависит от компилятора.На моем ПК было найдено следующее:
      • Intel 12.0.4 использует скорость счета 10000 из-за точности INTEGER.
      • gcc-4.4.5 использует 1000, не знаю, как это дифференцирует
    4. Склонен встречать обтекания , т.е. если c1 > c2, из-за count_max
    5. Время от одного стандартного времени.Таким образом, это приведет к фактическому времени одного потока, а не к сумме.

Код:

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 с -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  
    

Спасибо за чтение ...

Ответы [ 4 ]

18 голосов
/ 30 июля 2011

Эти две встроенные функции сообщают о различных типах времени.system_clock сообщает "время стены" или истекшее время.cpu_time сообщает время, используемое процессором.На многозадачной машине они могут сильно отличаться, например, если ваш процесс совместно использует ЦП в равной степени с тремя другими процессами и, следовательно, получает 25% ЦП и использует 10 процессорных секунд, это займет около 40 секунд фактического истечения времени или времени ожидания.время на часах.

5 голосов
/ 30 июля 2015

cpu_time () обычно имеет разрешение около 0,01 секунды на процессорах, совместимых с Intel.Это означает, что меньший интервал времени может считаться нулевым временем.В большинстве современных компиляторов для Linux разрешение system_clock () зависит от типов данных аргументов, поэтому целочисленное значение (int64) даст разрешение лучше 1 мкс, а также позволит вести подсчет в течение значительного промежутка времени.gfortran для Windows был недавно изменен (в течение 2015 года), чтобы сделать system_clock () эквивалентным вызовам query_performance.Однако ifort Windows по-прежнему показывает разрешение около 0,01 для system_clock, даже после того, как omp_get_wtime было изменено для использования query_performance.Я бы не стал принимать во внимание предыдущие комментарии об измерении разрешения cpu_time или system_clock в тактах, особенно если это может быть связано с тиковым сигналом процессора или шины данных, таким как инструкция rdtsc.

3 голосов
/ 27 февраля 2014

Я считаю itime (см. руководство пользователя gfortran ) хорошей альтернативой system_clock для синхронизации программ на фортране.Это очень легко использовать:

integer, dimension(3) :: time
call itime(time)
print *, 'Hour:  ', time(1)
print *, 'Minute:', time(2)
print *, 'Second:', time(3)
0 голосов
/ 30 июля 2011

Я считаю, что secnds () - это самый простой способ получить время на стене.Его использование почти идентично cpu_time ().

real(8)::t1,delta
t1=secnds(0.0)
!Do stuff
delta=seconds(t1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...