Fortran + Openmp比顺序更慢

时间:2013-03-12 13:46:19

标签: fortran openmp

我在Fortran中有这个顺序代码。我的问题是,当我使用Openmp指令时,并行代码比顺序代码更慢,我没有看到错误。

REAL, DIMENSION(:), ALLOCATABLE :: current, next
ALLOCATE ( current(TOTAL_Z), next(TOTAL_Z))

CALL CPU_TIME(t1)

!$OMP PARALLEL SHARED (current, next) PRIVATE (z)
DO t = 1, TOTAL_TIME
    !$OMP  DO SCHEDULE(STATIC, 2)
    DO z = 2, (TOTAL_Z - 1)
        next(z) = current (z) + KAPPA*DELTA_T*((current(z - 1) - 2.0*current(z) +      current(z + 1)) / DELTA_Z**2)
    END DO
    !$OMP END DO
    current = next
END DO

CALL CPU_TIME(t2)

!$OMP END PARALLEL 

TOTAL_Z,TOTAL_TIME,KAPPA,DELTA_T,DELTA_Z是常量。
当我运行并行代码时,我在htop中看到,我的2个内核正在以100%的速度运行 在顺序代码中,CPU_TIME是79 seg并且并联是132 seg
谢谢

3 个答案:

答案 0 :(得分:2)

我刚遇到同样的问题。

似乎使用cpu_time()不适合测量多线程代码的性能。 cpu_time()将添加所有线程的总时间,这可能会随着线程数量的增加而增加。

我在另一个论坛发现了这个, http://software.intel.com/en-us/forums/topic/281897

您应该使用system_clock()或omp_get_wtime()函数来更准确地计算日常工作。

答案 1 :(得分:1)

由于线程争用访问shared变量,因此可能很慢。如果您可以将其更改为使用reduction,则可能会更快。但这可能并不容易,因为“current”的计算会访问多个数组元素。

答案 2 :(得分:0)

取决于迭代次数,您可能还会面临嵌套数组上的错误共享问题。由于DO循环分布的块大小相当小,因此nest(z),nest(z + 1),nest(z + 2),nest(z + 3)等的缓存行可能会在CPU的L1 / L2缓存。

干杯,         -Michael