简单DO循环的自动并行化 - 内存参考过于复杂

时间:2017-01-09 17:25:39

标签: arrays parallel-processing fortran fortran90

我正在使用Absoft pro Fortran,我有一段代码如下:

program test1

INTEGER :: q, CAPQ, ingrid(1:6), outgrid(1:10)

ingrid = (/1,2,3,4,5,6/)
outgrid = 0
CAPQ = 6

DO q=1,CAPQ
      outgrid(q) = ingrid(q)
ENDDO

END

但是,当我构建它时,它不会自动并行化,因为:

  

索引变量Q的循环无法并行化,因为它包含的间接内存引用太复杂而无法成功分析。

然而这是一个非常简单的内存访问,我只是从数组中调用数字并将其放入另一个数组中。无论发生什么顺序都无关紧要,因此可以并行化。

1 个答案:

答案 0 :(得分:0)

我不熟悉Absoft Fortran,但我可以说我还没有找到一个在自动并行化方面做得很好的编译器。无论如何,这是一项艰巨的任务,我不会屏住呼吸等待编译器能够并行化代码,即使你自己完成也能实现。我强烈建议您考虑使用OpenMP(或您可能选择的任何并行化库)并行化代码。这并不困难,它确实得到了回报,特别是如果你对代码的“瓶颈”进行并列化。在这个特定的例子中,代码可以很容易地解释为

program test1
use omp_lib
implicit none

integer :: q, CAPQ, ingrid(1:6), outgrid(1:6)

ingrid=(/1,2,3,4,5,6/)
outgrid=0
CAPQ=6

!$omp parallel do private(q)
do q=1,CAPQ
  outgrid(q)=ingrid(q)
  print "(2(a,i0))","q=",q," processed by thread ",omp_get_thread_num()
end do
!$omp end parallel do

end program test1

请注意,我添加了一个print语句来验证可执行文件是否确实并行运行了do-loop。使用和不使用两个!#omp语句编译并运行示例以查看差异。启用并行化后,您应该看到类似

的内容
q=6 processed by thread 5
q=4 processed by thread 3
q=5 processed by thread 4
q=2 processed by thread 1
q=3 processed by thread 2
q=1 processed by thread 0
如果禁用并行化,

并且线程应该在任何地方为零。

上面的例子是gfortran,必须使用-fopenmp指令编译。 根据您使用的编译器,语句use omp_lib可能需要替换为类似的东西,编译器指令也可能略有不同。根据我在网上找到的Absoft Pro Fortran用户指南,编译器指令是-openmp。用户指南还提到了“积极的OpenMP”并行化的选项,这绝对值得一看。