OpenMP и проблема распараллеливания - PullRequest
1 голос
/ 11 сентября 2011

Я занимаюсь исследованиями в лаборатории вычислительной электромагнетики с суперкомпьютерами. Здесь мы работаем с кластерами, чтобы решить проблемы, включающие более 500 миллионов неизвестных. На данный момент у нас есть проблема с распараллеливанием всех этих вычислений. До сих пор мы работали с MPI для обмена данными между узлами, однако мы собираемся принять решение об использовании OpenMP для обеспечения связи между процессорами в узле с точки зрения преимуществ OpenMP. Несмотря на это, мы не смогли получить какую-либо эффективность от openMP (возможно, из-за ложного кодирования). На самом деле дело в том, что я не знаю, что не так с кодом, который я дам.

Он работает одновременно с чистым последовательным кодом без каких-либо директив OpenMP. Когда я использовал команду 'top', 8 процессоров работали с производительностью% 100 во время секции paralllel.

Гфортран - версия | голова -1 GNU Fortran (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)

PROGRAM dotproduct
    USE omp_lib   
    IMPLICIT none 

    INTEGER ::h,m,i,TID,NTHREADS,j,ierr

    REAL :: start,end
    REAL, ALLOCATABLE, DIMENSION(:,:) :: a
    REAL, ALLOCATABLE, DIMENSION(:) :: x
    REAL, ALLOCATABLE, DIMENSION(:) :: b

    m= 20000
    OPEN(UNIT=1,FILE='matrix20000.dat',STATUS='UNKNOWN')
    OPEN(UNIT=2,FILE='vector20000.dat',STATUS='UNKNOWN')

    ALLOCATE(a(m,m)) 
    ALLOCATE(x(m))
    ALLOCATE(b(m))
    REWIND(1)
    REWIND(2)

    WRITE(*,*) ' Reading is just started'

    READ(1,*), a(:,:) 
    READ(2,*), x(:)

    WRITE(*,*) ' Reading is over'
    WRITE(*,*) ' Calculating will be started after parallelization'

    !$OMP PARALLEL PRIVATE(i,TID,j),SHARED(NTHREADS,m,a,x,b)
    TID= omp_get_thread_num()
    IF(TID == 0) THEN
      NTHREADS = OMP_GET_NUM_THREADS()
      PRINT*, 'Starting matrix multiple example with', NTHREADS
    END IF
    CALL cpu_time(start)
    !$OMP DO
          DO i=1, m
             b(i)= 0
             DO j=1, m
                b(i) = b(i)+ a(i,j)*x(j)
             END DO
          END DO
    !$OMP END DO
    !$OMP END PARALLEL
    CALL cpu_time(end)

    WRITE(*,*) end-start,' seconds'

    !DO i=1,m
    !   WRITE(*,*) b(i)
    !END DO

    DEALLOCATE(a)                     !----Deallocation
    DEALLOCATE(x)
    DEALLOCATE(b)


    END PROGRAM dotproduct

Ответы [ 2 ]

1 голос
/ 15 сентября 2011

Классическая ошибка - Cpu_time обычно измеряет общее время ЦП, что означает, что оно суммируется по всем потокам!Следовательно, идеальное ускорение приводит к постоянному времени независимо от количества потоков

Попробуйте измерить время на стене с помощью system_clock или аналогичного и посмотрите, что вы получите.

Кстати, почему nthreads используется совместно?Лучше сохранить как можно больше секретов

(извините, если это появляется дважды, первое усилие ...)

0 голосов
/ 11 сентября 2011

Похоже, конфликтует проблема доступа к памяти. Все процессы обращаются к общему x (j). Хотя это не является реальным решением, вы можете попытаться продублировать x в каждом потоке, чтобы посмотреть, поможет ли это.

...