Fortran+;Openmp的速度比串行的慢

Fortran+;Openmp的速度比串行的慢,fortran,openmp,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 !$O

我用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 
总时间、总时间、KAPPA、δT、δZ是常数。
当我运行并行代码时,我在htop中看到,我的两个内核都在100%工作
在顺序代码中,CPU_时间为79 seg,在并行代码中为132 seg

感谢

这可能很慢,因为线程正在争用
共享
变量。如果您可以将其更改为使用
reduce
,它可能会更快。但这可能并不容易,因为“current”的计算会访问多个数组元素。

这可能很慢,因为线程正在争夺访问共享的
变量。如果您可以将其更改为使用
reduce
,它可能会更快。但这可能并不容易,因为“current”的计算会访问多个数组元素。

我刚刚遇到了同样的问题

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

我在另一个论坛上发现了这个,


您应该使用system_clock()或omp_get_wtime()函数来获得更精确的例程计时。

我刚刚遇到了同样的问题

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

我在另一个论坛上发现了这个,


您应该使用system_clock()或omp_get_wtime()函数来获得更精确的例程计时。

根据迭代次数的不同,您可能还面临嵌套数组上错误共享的问题。由于DO循环分布的块大小相当小,因此nest(z)、nest(z+1)、nest(z+2)、nest(z+3)等的缓存线可能在CPU的一级/二级缓存之间来回摆动

干杯,
-michael

根据迭代次数的不同,您可能还面临嵌套数组上错误共享的问题。由于DO循环分布的块大小相当小,因此nest(z)、nest(z+1)、nest(z+2)、nest(z+3)等的缓存线可能在CPU的一级/二级缓存之间来回摆动

干杯,
-michael

您的代码有一个竞赛条件。所有线程都使用索引变量
t
执行外部循环。在该循环中,所有线程都执行赋值
current=next
。所有线程都在写入相同的内存位置,没有任何同步。您的代码存在争用条件。所有线程都使用索引变量
t
执行外部循环。在该循环中,所有线程都执行赋值
current=next
。所有线程都在写入相同的内存位置,而不进行任何同步。