我正在使用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的循环无法并行化,因为它包含的间接内存引用太复杂而无法成功分析。
然而这是一个非常简单的内存访问,我只是从数组中调用数字并将其放入另一个数组中。无论发生什么顺序都无关紧要,因此可以并行化。
答案 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”并行化的选项,这绝对值得一看。