1

저는 컴퓨터로 전자기 연구실을 슈퍼 컴퓨터로 연구하고 있습니다. 여기서 우리는 500M 이상의 미지의 문제를 해결하기 위해 클러스터와 협력하고 있습니다. 이 시점에서 모든 계산을 병렬화하는 데 문제가 있습니다. 지금까지 우리는 노드 간 통신을 위해 MPI와 협력 해 왔지만 OpenMP를 사용하여 노드의 프로세서 간 통신을 가능하게 결정할 예정입니다. 그럼에도 불구하고, 우리는 openMP로부터 어떠한 효율성도 얻지 못했습니다 (아마도 잘못된 코딩 때문에). 사실 요점은 내가 줄 코드에 무엇이 잘못되었는지 모른다는 것입니다.OpenMP 및 병렬 문제

OpenMP 지시어가없는 순차적 인 순수 코드로 같은 시간이 걸렸습니다. 'top'명령어를 사용할 때, 프로세서는 paralllel 섹션에서 % 100 성능으로 작업하고있었습니다.

gfortran --version | 머리 -1 GNU 포트란 (GCC) 4.1.2 20080704 (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

OMP 지원 4.1 성능 저하 악명이었다 지금 gcc 레드햇 다시 이식. 나는 다른 것을하기 전에 더 현대적인 컴파일러를 살펴볼 것을 권한다. – talonmies

+1

gcc 4.1이 성능 저하의 주요 원인입니다. paralellization이없는 것처럼 보이기 때문에 실제로 "성능 저하"라고하는 것이 맞습니다. – Yigit

+0

정확히 어떻게 런타임을 측정합니까? cpu_time의 출력을 사용하면 모든 스레드의 누적 시간이 표시됩니다. MPI를 사용한다면 MPI_wtime을 사용하여 실제 실시간을 가져와야합니다. 컴파일러에 관해서는 GCC 구현이 4.1 에서조차 좋지 않을 것이라고 생각합니다. 그래도 컴파일러를 전환해도 OpenMP 확장 기능이 향상 될 수 있습니다. – haraldkl

답변

0

이 충돌하는 메모리 접근 문제처럼 보인다. 모든 프로세스는 공유 된 x (j)에 접근합니다. 비록 실제 해결책은 아니지만, 각 스레드에서 x를 복제하여 이것이 도움이되는지 확인할 수 있습니다.

+0

각 스레드에 x를 복제하면 무엇을 의미합니까? – Yigit

+0

각 tid에 대해 동일한 내용을 갖는 x (j, tid)와 같은 것을가집니다. – haraldkl

+0

아마 : http://people.sc.fsu.edu/~jburkardt/f_src/mxv_open_mp/mxv_open_mp.f90 또한 OpenMP에서 행렬 벡터 곱셈의 작업 공유 버전을 가지고 있습니다. – haraldkl

1

클래식 오류 - 일반적으로 Cpu_time은 총 CPU 시간을 측정합니다. 즉, 모든 스레드에서 합산됩니다. 따라서 완벽한 속도 향상은 스레드 수에 관계없이 일정한 시간을 가져옵니다.

system_clock 또는 유사한 방법으로 벽 시간을 측정하고 얻은 결과를 확인해보십시오.

왜 - nthreads가 공유되어 있습니까? 그것은 개인만큼을 유지하는 것이 가장 좋습니다 (...이 두 번 나타나는 경우 죄송합니다, 첫 번째 노력)

가능한