Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 简单DO循环的自动并行化-内存引用太复杂_Arrays_Parallel Processing_Fortran_Fortran90 - Fatal编程技术网

Arrays 简单DO循环的自动并行化-内存引用太复杂

Arrays 简单DO循环的自动并行化-内存引用太复杂,arrays,parallel-processing,fortran,fortran90,Arrays,Parallel Processing,Fortran,Fortran90,我正在使用Absolft 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的循环无法并行化,因为它包含一个间接内存引用

我正在使用Absolft 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的循环无法并行化,因为它包含一个间接内存引用,该引用太复杂,无法成功分析


但这是一个非常简单的内存访问,我只是从数组中调用这个数字,然后将它放入另一个数组中。它的出现顺序应该无关紧要,因此可以并行化。

我不熟悉Absolft 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循环。编译并运行带有和不带这两个
的示例#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
,编译器指令也可能略有不同。根据我在网上找到的Absolft Pro Fortran用户指南,编译器指令是-openmp。《用户指南》还提到了“积极的OpenMP”并行化选项,这些选项绝对值得一看。

编译器必须避免并行化,因为线程之间的存储距离不超过128字节,这将导致错误共享。有没有办法解决这一问题,为了不禁止并行化?我删除了对OpenMP的引用:OpenMP不包括自动并行化,并且我找不到Absolft pro使用OpenMP进行自动并行化的引用。如果您认为它真的与OpenMP有关,请澄清。@tim18您能再解释一下您的意思吗?以及如何避免这种情况。非常感谢。如果打算使用OpenMP,则需要一些OpenMP指令。我会在propgram之后和缺少的隐式none之前使用OMP。为了避免误解,并行化do循环并不总是像Laurence_jj发布的测试示例那样简单。我可以想象do循环中的实际代码要比简单赋值复杂得多(你可以通过移除do循环并用一个简单的
outgrid(1:CAPQ)=ingrid(1:CAPQ)
替换它)。根据循环中的内容,可能需要特别注意,包括其他OpenMP功能。更糟糕的是:在某些情况下,do循环根本无法并行化。