如何确保我的Fortran FORALL构造被并行化?

EMi*_*ler 6 parallel-processing fortran forall

我已经获得了一个2D矩阵,表示金属板表面的温度点.基质(板)的边缘保持恒定在20摄氏度,并且在一个预定点处存在100摄氏度的恒定热源.所有其他网格点最初设置为50摄氏度.

我的目标是通过对周围的四个网格点(i + 1,i-1,j + 1,j-1)进行迭代平均来获取所有内部网格点并计算其稳态温度,直到达到收敛(迭代之间小于0.02摄氏度).

据我所知,迭代网格点的顺序是无关紧要的.

对我来说,这听起来像是调用Fortran FORALL构造并探索并行化乐趣的好时机.

如何确保代码确实是并行化的?

例如,我可以在我的单核PowerBook G4上编译它,并且由于并行化,我预计速度不会提高.但如果我在双核AMD Opteron上编译,我会假设FORALL结构可以被利用.

或者,有没有办法衡量程序的有效并行化?

更新

回答MSB的问题,这是与gfortran版本4.4.0.gfortran是否支持自动多线程?

值得注意的是,FORALL结构已被淘汰,我想,那就是自动向量化.

也许这对于一个单独的问题是最好的,但自动矢量化是如何工作的?编译器是否能够检测到循环中只使用纯函数或子例程?

Bri*_*ian 7

FORALL是赋值构造,而不是循环构造.FORALL的语义表明FORALL中每个赋值的右侧表达式(RHS)在被分配到左侧(LHS)之前完全被评估.无论RHS上的操作有多复杂,包括RHS和LHS重叠的情况,都必须这样做.

大多数编译器都在优化FORALL,因为它很难优化,因为它不常用.最简单的实现是简单地为RHS分配一个临时表,计算表达式并将其存储在临时表中,然后将结果复制到LHS中.分配和释放此临时文件可能会使您的代码运行得非常慢.编译器很难自动确定何时可以在没有临时的情况下评估RHS; 大多数编译器都没有尝试这样做.嵌套的DO循环变得更容易分析和优化.

对于一些编译器,您可以通过将FORALL与OpenMP"workshare"指令一起包含并使用启用OpenMP所需的任何标志进行编译来并行化RHS的评估,如下所示:

!$omp parallel workshare
FORALL (i=,j=,...)
    <assignment>
END FORALL
!$omp end parallel
Run Code Online (Sandbox Code Playgroud)

gfortran -fopenmp blah.f90 -o blah

请注意,不需要兼容的OpenMP实现(至少包括旧版本的gfortran)来并行评估RHS; 实现可以接受评估RHS,就好像它包含在OpenMP"单一"指令中一样.另请注意,"工作共享"可能不会消除RHS分配的临时工作.例如,在Mac OS X上使用旧版本的IBM Fortran编译器就是这种情况.


exf*_*zik 6

如果使用英特尔Fortran编译器,则可以使用命令行开关打开/增加编译器的详细级别以进行并行化/矢量化.这种方式在编译/链接期间,您将显示如下内容:

FORALL loop at line X in file Y has been vectorized
Run Code Online (Sandbox Code Playgroud)

我承认自上次使用它以来已经过了几年,因此编译器消息实际上可能看起来非常不同,但这是基本的想法.