我有三个嵌套循环。我想将中间循环并行化:
do a = 1,amax
!$omp parallel do private(c)
do b = 1,bmax
do c = 1,cmax
call mysubroutine(b,c)
end do
end do
!$omp end parallel do
end do
然而,这会产生一个问题,因为对于a
循环的每次迭代,线程都会产生,通过内部循环运行,然后终止。我认为这会导致过多的开销,因为内部循环执行时间不长(~10^-4
)。所以我想只生成一次线程。如何在启动a
循环之前生成线程,同时仍然按顺序执行a
循环?由于代码的性质,a
循环的每次迭代必须在下一次执行之前完成。例如,显然这不起作用:
!$omp parallel private(c)
do a = 1,amax
!$omp do
do b = 1,bmax
do c = 1,cmax
call mysubroutine(b,c)
end do
end do
!$omp end do
end do
!$omp end parallel
因为所有线程都会尝试执行a
循环。任何帮助赞赏。
“例如,显然这不起作用”
这不仅不清楚,这是完全错误的。您展示的代码正是您应该做的(使用private(a)
更好)。
“因为所有线程都会尝试执行一个循环”
他们当然会,他们必须!如果他们应该参加omp do
内循环的工作共享,所有人都必须执行它!如果他们不执行它,他们根本就不会帮助内循环。
另一种说法:您可能会受益于collapse(2)
嵌套循环的omp do
子句。
断言“这会导致过多的开销”的好方法是使用不同数量的线程来评估缩放。
1s是很长一段时间,重生螺纹不是那么昂贵......