不具有任何交叉迭代数据依赖性的 DO 循环由 -autopar 自动并行化。自动并行化的一般标准是:
只有显式 DO 循环和隐式循环(如 IF 循环和 Fortran 95 数组语法)才可以并行化。
循环内每个迭代的数组变量值不能依赖于循环内任何其他迭代的数组变量值。
循环中的计算不能有条件地改变循环终止后引用的任何纯标量变量。
循环中的计算不能在各次迭代间改变标量变量。这称为循环携带依赖性。
循环体内的工作量必须要超过并行化开销。
编译器可以自动消除显示的引用以在循环中创建数据依赖性。这种转换有许多,其中之一会利用某些数组的专用版本。通常,如果编译器能确定这种数组在原始循环中只是作为临时存储使用,它便会这样做。
示例:使用 -autopar,通过专用数组消除了依赖性:
parameter (n=1000) real a(n), b(n), c(n,n) do i = 1, 1000 <--Parallelized do k = 1, n a(k) = b(k) + 2.0 end do do j = 1, n-1 c(i,j) = a(j+1) + 2.3 end do end do end |
在此例中,外层循环被并行化,并在独立的处理器上运行。虽然内层循环对数组 a 的引用看起来会导致数据依赖性,但编译器会生成数组的临时专用副本,使外层循环迭代变得独立。
在自动并行化过程中,如果以下条件下成立,编译器不会对循环进行并行化:
DO 循环嵌套在已并行化的另一 DO 循环内。
流控制允许跳出 DO 循环。
用户级子程序在循环内被调用
循环中有 I/O 语句
循环内的计算会改变具有别名的标量变量
在多线程多处理器环境中,对循环嵌套中最外层循环(而不是最内层循环)进行并行化最有效。由于并行处理通常涉及相对较大的循环开销,所以并行化最外层循环会最大程度地减少开销并增加每个线程完成的工作量。在自动并行化情况下,编译器从最外层嵌套循环开始进行循环分析,然后继续向内进行直至找到可并行化的循环。一旦嵌套中的某个循环被并行化,便会略过该并行循环内所包含的循环。