【问题标题】:Why OpenMP do-loop that actually generates parallel process, can NOT be detected by OMP_GET_THREAD_NUM()?为什么 OMP_GET_THREAD_NUM() 检测不到实际生成并行进程的 OpenMP do-loop?
【发布时间】:2015-09-16 10:42:18
【问题描述】:

我不明白为什么 !$OMP DO 实际上是将任务分配给不同的线程,但使用 openMP 内部函数 OMP_GET_THREAD_NUM() 无法检测到。

program test
implicit none

integer :: i,su
double precision a(10), b(10),c
INTEGER OMP_GET_THREAD_NUM

su=0


!$OMP DO
do i=1,10
   b(i) = 10*i;
   c = b(i);   
   write(*,*)'in the loop, rank =',c,OMP_GET_THREAD_NUM()
enddo
!$OMP END DO

!$OMP PARALLEL
write(*,*) 'Rank = ',OMP_GET_THREAD_NUM()
!$OMP END PARALLEL

end

结果是:

 in the loop, rank =   10.000000000000000                0
 in the loop, rank =   20.000000000000000                0
 in the loop, rank =   30.000000000000000                0
 in the loop, rank =   40.000000000000000                0
 in the loop, rank =   50.000000000000000                0
 in the loop, rank =   60.000000000000000                0
 in the loop, rank =   70.000000000000000                0
 in the loop, rank =   80.000000000000000                0
 in the loop, rank =   90.000000000000000                0
 in the loop, rank =   100.00000000000000                0
 Rank =            0
 Rank =            6
 Rank =            1
 Rank =            7
 Rank =            2
 Rank =            5
 Rank =            4
 Rank =            3

看到了吗?在 DO-LOOP 中,公众似乎只能看到 Master 线程。这是不公平的,因为这不是他唯一的一项贡献。

【问题讨论】:

  • !$OMP DO -- 看起来你忘了实例化一个并行区域。试试!$OMP PARALLEL DO
  • 谢谢!我得到了它!我被网站上的 F95 手册误导了。它包含了很多我觉得分散的东西。所以我认为 !$OMP PARALLEL DO 等于首先 !$OMP PARALLEL 然后下一行: !$OMP DO 。对吗?

标签: fortran openmp


【解决方案1】:

您的do 循环不在并行区域中,因此未并行化——所有循环索引由线程 0 处理。

如果我将您的程序更改为包含并行区域

...
!$OMP PARALLEL
!$OMP DO
do i=1,10
   b(i) = 10*i;
   c = b(i);
   write(*,*)'in the loop, rank =',c,OMP_GET_THREAD_NUM()
enddo
!$OMP END DO
!$OMP END PARALLEL
...

然后我得到 OMP 线程号的正确输出:

 in the loop, rank =   50.000000000000000                8
 in the loop, rank =   20.000000000000000                3
 in the loop, rank =   20.000000000000000                7
 in the loop, rank =   20.000000000000000                4
 in the loop, rank =   20.000000000000000                5
 in the loop, rank =   20.000000000000000                9
 in the loop, rank =   20.000000000000000                6
 in the loop, rank =   20.000000000000000                0
 in the loop, rank =   20.000000000000000                1
 in the loop, rank =   30.000000000000000                2

这个特定的输出也暴露了你的代码中的一个缺陷,即c 是共享的,所以它的值被每个线程破坏了。此外,如果 do 循环是并行区域中唯一的内容,您可以组合 OMP 指令。最后,如果我们将您的代码更改为:

!$OMP PARALLEL DO private(c)
do i=1,10
   b(i) = 10*i;
   c = b(i);
   write(*,*)'in the loop, rank =',c,OMP_GET_THREAD_NUM()
enddo
!$OMP END PARALLEL DO

那么输出将是正确的。

 in the loop, rank =   100.00000000000000                9
 in the loop, rank =   30.000000000000000                2
 in the loop, rank =   20.000000000000000                1
 in the loop, rank =   70.000000000000000                6
 in the loop, rank =   60.000000000000000                5
 in the loop, rank =   50.000000000000000                4
 in the loop, rank =   80.000000000000000                7
 in the loop, rank =   90.000000000000000                8
 in the loop, rank =   10.000000000000000                0
 in the loop, rank =   40.000000000000000                3

【讨论】:

  • @PabPeter 如果答案对您有用,您可以通过投票表示感谢(多一点代表),如果它解决了您的问题,您可以通过接受它来表示感谢(单击复选标记网络以答案)。
  • 对不起,我不能,因为我的声望低于 15。
  • @PabPeter 我知道你还不能投票,但你可以接受。
猜你喜欢
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 2022-11-29
  • 2017-05-18
相关资源
最近更新 更多