我有一个Fortran代码,我试图与OpenMP并行化,我是一个初学者。它由一个嵌套循环组成,其中最里面的循环是最大的并且是最佳的并行化目标。一个重要的变量var
在较小的外部循环(索引i
)中定义,并由内部循环中的所有迭代使用(索引j
)。
当只对内部循环进行并行化时,我观察到所有可用的线程都不会在下一次外部迭代中使用,直到完成内部循环的所有计算,如预期的那样。但是,我预测这将是对群集上计算时间的低效使用。我想允许外循环继续并在下一个var
索引中定义新的i
,并在前一个j
循环完成时继续下一个j
索引起来。你会怎么推荐这样做?
对于内循环处理,我尝试使用NOWAIT说明符,但这会导致外循环每次都创建var
,这同样效率低下。如何指导程序将var
保存为进入新i
索引的每个线程的数据?
以下是我现在所拥有的一个例子:
program Test
integer::i,j
double precision::inp1(10) !array of unique input values
double precision::val,output
...
!$OMP PARALLEL
!$OMP&DEFAULT(SHARED)
!$OMP&PRIVATE(val,output,i,j)
do i=1,10 !small loop
!create val just once and use in relevant j index
call mysub1(inp1(i),val)
...
!$OMP DO
do j=1,100000 !ton of iterations in this loop
call mysub2(val,output)
!do things with output
...
end do !for j
!if threads are available, don't wait for j to finish
!and move on to next i iteration
!$OMP END DO NOWAIT
end do !for i
!$OMP END PARALLEL
...
end program
subroutine mysub1(inp1,val)
!(do things with inp1 and calculate val)
...
return
end subroutine
subroutine mysub2(val,output)
!(do things with val and create output)
...
return
end subroutine
我想答案很简单,但我现在有点迷失了!我是否在SINGLE
周围使用TASK
或mysub1
结构?