在非并行时间相关的do循环中并行使用OpenMP部分

时间:2014-09-16 17:19:36

标签: multithreading parallel-processing fortran openmp

我对OpenMP有一个简单的问题。通常人们可以像这样做一个平行的部分(用fortran编写,有两个部分):

!$OMP PARALLEL SECTIONS

!$OMP SECTION

< Fortran code block A>

!$OMP SECTION

< Fortran code block B>

!$OMP END SECTIONS

现在我真的想在do循环中运行fortran代码块A和B,它本身不应该并行化,因为这个do循环是一个依赖于时间的循环,每个新步骤都依赖于前一步的结果。在并行部分之前,我需要运行一个串行代码(让我们称之为块C)。现在块A,B,C都是do循环变量t的函数。然后天真地可以通过简单地将这个并行嵌入到do循环中来提出这样的代码:

do t=1:tmax

  < Fortran serial code block C>

  !$OMP PARALLEL SECTIONS

  !$OMP SECTION

  < Fortran code block A>

  !$OMP SECTION

  < Fortran code block B>

  !$OMP END SECTIONS

end do

然而,显而易见的是,线程开销的创建将在很大程度上减慢此速度,这甚至可能使其比标准串行代码慢。因此,人们可能会提出更聪明的想法来解决这个问题。

我想知道你是否可以帮助我提供一些如何做到这一点的提示。什么是最好的方法(最快的计算)?

1 个答案:

答案 0 :(得分:1)

我同意这两条评论,即将OpenMP开销与计算进行比较的程度并不明显。如果你发现它(在执行相应的测量之后)非常高,那么处理这种情况的典型方法是将循环放在一个平行区域内:

!$OMP PARALLEL PRIVATE(t)
do t=1,tmax

  !$OMP SINGLE
    < Fortran code block C >
  !$OMP END SINGLE

  !$OMP SECTIONS

    !$OMP SECTION
    < Fortran code block A >

    !$OMP SECTION
    < Fortran code block B >

  !$OMP END SECTIONS

end do
!$OMP END PARALLEL

每个线程将独立循环。 SECTIONS构造在其末尾具有隐式屏障,因此线程在下一个循环迭代之前被同步。如果在并行区域结束之前有一些不同步的附加代码,则必须在end do之前插入显式屏障。

SINGLE构造用于隔离块C,使其仅由一个线程执行。