使用OpenMP for FORTRAN90的嵌套DO循环的低性能

时间:2011-11-02 18:22:43

标签: openmp fortran90

我正在尝试并行部分代码,如下所示

    !$OMP PARALLEL PRIVATE(j,x,y,xnew, ynew) SHARED(xDim, yDim, ex, f, fplus)
    !$OMP DO
    DO j = 1, 8
        DO y=1, yDim
            ynew = y+ey(j)
            DO x=1, xDim
                xnew = x+ex(j)
                IF ((xnew >= 1 .AND. xnew <= xDim) .AND.  (ynew >= 1 .AND. ynew <= yDim))  f(xnew,ynew,j)=fplus(x,y,j)
            END DO
        END DO
    END DO
    !$OMP END DO
    !$OMP END PARALLEL

我是OpenMP和FORTRAN的新手。单核提供了更好的并行代码性能。请告诉我在这里犯的错误..

2 个答案:

答案 0 :(得分:3)

这里的问题是你只是复制一个数组切片 - 这里没有什么真正的CPU限制,在核心之间拆分会有很大帮助。最终这个问题是内存限制,将数据从一个内存复制到另一个内存,并且增加一次工作的CPU数量可能只会增加争用。

话虽如此,如果我稍微修改循环以获得if循环内部的声明,我可以获得小的(~10%)加速。这样:

CALL tick(clock)
!$OMP PARALLEL PRIVATE(j,x,y,xnew, ynew) SHARED(ex, ey, f, fplus) DEFAULT(none)
!$OMP DO
DO j = 1, 8
    DO y=1+ey(j), yDim
        DO x=1+ex(j), xDim
            f(x,y,j)=fplus(x-ex(j),y-ey(j),j)
        END DO
    END DO
END DO
!$OMP END DO
!$OMP END PARALLEL
time2 = tock(clock)

或者这个:

CALL tick(clock)
!$OMP PARALLEL PRIVATE(j,x,y,xnew, ynew) SHARED(ex, ey, f, fplus) DEFAULT(none)
!$OMP DO
DO j = 1, 8
    f(1+ex(j):xDim, 1+ey(j):yDim, j) = fplus(1:xDim-ex(j),1:yDim-ey(j),j)
ENDDO
!$OMP END DO
!$OMP END PARALLEL
time3 = tock(clock)

进行非常适度的改进。如果fplus是参数x,y和j的函数并且是计算密集型的,那么事情会有所不同;但内存副本不太可能加快。

答案 1 :(得分:0)

您的表现还取决于循环的大小。你有正确的循环安排,在外循环上最右边的索引可以获得更优化的内存访问。如果这些循环很小并且所有内存都可以放在单个处理器的缓存中,那么使用OpenMP可能不会提高性能。如您所见,由于OpenMP开销(例如线程创建/销毁),您实际上可以看到性能下降。并且在将来,尽量避免在嵌套循环中使用IF语句,它们会严重损害您的性能!

相关问题