我在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
谢谢
答案 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