我正在用超級計算機研究計算電磁學實驗室。在這裏,我們正在與羣集一起解決包括超過500M未知數的問題。在這一點上,我們有一個平行化所有這些計算的問題。到目前爲止,我們一直在與MPI一起在節點之間進行通信,但是,我們即將決定使用OpenMP來實現節點中處理器之間的OpenMP通信的優勢。儘管如此,我們無法從openMP中獲得任何效率(可能是因爲虛假編碼)。其實問題是我不知道我會給出的代碼有什麼問題。OpenMP和並行化問題
與沒有任何OpenMP指令的順序純代碼相同。當我使用'top'命令時,8個處理器在paralllel部分使用%100的性能。
gfortran --version |頭-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
的OMP支持的紅帽回移植到GCC 4.1是臭名昭著的表現不佳。我建議在做其他事情之前先看看更現代的編譯器。 – talonmies
可能gcc 4.1是這種糟糕性能的主要原因。事實上,把它稱爲「糟糕的性能」是正確的,因爲它看起來像沒有平行。 – Yigit
剛纔我想到,你究竟如何測量運行時間?如果您使用cpu_time的輸出,您將獲得所有線程的累計時間。如果您仍然使用MPI,則應該使用MPI_wtime來獲取實際的實時。關於編譯器,我認爲即使在4.1版本中,GCC實現也不會太壞,但仍然可以改變編譯器也可以改進OpenMP縮放。 – haraldkl