Parallel processing 在Fortran OpenMP代码中,每次迭代仅执行一次任务
我有一个Fortran代码,我正在尝试与OpenMP并行,我是一个初学者。它由一个嵌套循环组成,其中最里面的循环是最大的,也是并行化的最佳目标。一个重要变量Parallel processing 在Fortran OpenMP代码中,每次迭代仅执行一次任务,parallel-processing,fortran,openmp,nested-loops,Parallel Processing,Fortran,Openmp,Nested Loops,我有一个Fortran代码,我正在尝试与OpenMP并行,我是一个初学者。它由一个嵌套循环组成,其中最里面的循环是最大的,也是并行化的最佳目标。一个重要变量var在较小的外循环(索引i)中定义,并由内循环(索引j)中的所有迭代使用 当只并行内部循环时,我观察到所有可用的线程都不会在下一个外部迭代中使用,直到内部循环的所有计算完成,正如预期的那样。然而,我预测这将是对集群上计算时间的低效利用。我想让外部循环继续,在下一个I索引中定义新的var,并在上一个j循环结束时继续下一个j索引。你建议怎么做
var
在较小的外循环(索引i
)中定义,并由内循环(索引j
)中的所有迭代使用
当只并行内部循环时,我观察到所有可用的线程都不会在下一个外部迭代中使用,直到内部循环的所有计算完成,正如预期的那样。然而,我预测这将是对集群上计算时间的低效利用。我想让外部循环继续,在下一个I
索引中定义新的var
,并在上一个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
?迭代是否依赖于先前的迭代?为什么OMP DO
在i
循环内部而不是外部?显示需要您选择的实际代码可能会很有帮助。在堆栈溢出时欢迎,接受欢迎并阅读也会非常有用。此代码通常在多少线程上运行?如果它大约是i
-循环的数量,那么将i
并行化可能更明智-loop@VladimirFi
迭代是独立的。这段代码是基于一个旧的f90代码,其中有很多不应该是线程安全的公共块,我必须在这两个子例程周围使用关键标签来防止错误。我已经为外循环指定了并行do,但由于某些原因,巨大的内循环最终只得到一个线程。@Fl.pf。代码将有24个线程在手。给定一百次i
迭代,每个i
基本上都有自己的线程。由于var
是基于特殊的材料属性,选择inp1(i)
可以显著加快j
循环,这就是我希望主要并行化内部循环的原因。我只是想有效地利用时间。