1

我正在用超级计算机研究计算电磁学实验室。在这里,我们正在使用集群来解决包括超过 5 亿个未知数的问题。在这一点上,我们遇到了并行化所有这些计算的问题。到目前为止,我们一直在使用 MPI 在节点之间进行通信,但是,就 OpenMP 的优势而言,我们即将决定使用 OpenMP 来实现节点中的处理器之间的通信。尽管如此,我们无法从 openMP 获得任何效率(可能是因为错误编码)。实际上,关键是我不知道我将给出的代码有什么问题。

没有任何 OpenMP 指令的顺序纯代码需要相同的时间。当我使用“top”命令时,8 个处理器在并行部分以 %100 的性能工作。

gfortran --版本 | 头 -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
4

2 回答 2

1

经典错误 - Cpu_time 通常测量总 CPU 时间,这意味着它是所有线程的总和!因此,无论线程数如何,完美的加速都会产生恒定的时间

尝试使用 system_clock 或类似工具测量挂钟时间,看看你得到了什么。

顺便说一句 - 为什么要共享 nthreads?最好尽可能保持私密

(对不起,如果这出现两次,第一次努力......)

于 2011-09-15T09:12:13.277 回答
0

看起来像一个冲突的内存访问问题。所有进程都访问共享的 x(j)。虽然这不是真正的解决方案,但您可以尝试在每个线程上复制 x ,看看这是否有帮助。

于 2011-09-11T18:04:18.863 回答