我无法理解为什么!$ 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中只有公共人员可以看到主线程。这是不公平的,因为这不是他唯一的贡献。
答案 0 :(得分:1)
您的do
循环不在并行区域中,因此未并行化 - 所有循环索引都由处理。
如果我将程序更改为包含并行区域
...
!$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