我有一个伪代码,就像这样:
Do while loop
if condition
call subroutinex(In)
else
do i=2,max
ln=i
call subroutinex(ln)
end do
endif
other serial work
end do
我成功地将内循环并行化了
Do while loop
if condition
call subroutinex(In)
else
!$OMP PARALLEL DEFAULT (SHARED) PRIVATE (pr.variables)
!$OMP DO
do i=2,max
ln=i
call subroutinex(ln)
end do
!$OMP END DO
!$OMP END PARALLEL
endif
other serial work
end do
此代码可以很好地生成正确的结果,并且在优化的自动并行化NO-OMP版本的大约一半时间内运行(最大值= 5)。我怀疑(虽然不太确定)在“Do while循环”中产生并行区域可能会导致一些不必要的开销,我可以避免使用不同的方法(产生外部循环外的并行区域并使用!$ OMP关键或!$ OMP MASTER)。我似乎无法理解这样的正确语法是怎样的。任何建议都非常受欢迎。
祝你好运, 阿波斯托洛
答案 0 :(得分:0)
我认为你的伪代码的修改应该有效
!$OMP PARALLEL DEFAULT (SHARED) PRIVATE (pr.variables)
Do while loop
if condition
!$OMP SINGLE
call subroutinex(In)
!$OMP END SINGLE
else
!$OMP DO
do i=2,max
ln=i
call subroutinex(ln)
end do
!$OMP END DO
endif
!$OMP SINGLE
other serial work
!$OMP END SINGLE
end do
!$OMP END PARALLEL
您需要仔细检查变量的可访问性。
这可能无法带来显着的加速。进入并行区域的开销通常不包括启动一组线程的时间,而是激活在程序初始化时建立的团队。但请回报并告诉我这是否有效(a)是否有效以及(b)提高执行速度。
答案 1 :(得分:0)
或者,您可以浏览OpenMP任务,例如
!$OMP PARALLEL DEFAULT (SHARED) PRIVATE (pr.variables)
!$OMP SINGLE
Do while loop
if condition
call subroutinex(In)
else
do i=2,max
ln=i
!$OMP TASK firstprivate(ln)
call subroutinex(ln)
!$OMP END TASK
end do
!$OMP TASKWAIT
endif
other serial work
end do
!$OMP END SINGLE nowait
!$OMP END PARALLEL