我得到了一个二维矩阵,表示金属板表面的温度点。矩阵(板)的边缘保持在20℃不变,在一个预定义的点上有一个100℃的恒定热源。所有其他网格点最初被设置为50摄氏度。
我的目标是获取所有内部网格点,并通过对周围四个网格点(i+1、i-1、j+1、j-1)的迭代平均计算其稳态温度,直到达到收敛(迭代之间的变化小于0.02℃)。
据我所知,迭代网格点的顺序是不相关的。
在我看来,这似乎是调用Fortran FORALL构造并探索并行化的乐趣的好时机。
如何确保代码确实被并行化?
例如,我可以在我的单核PowerBook G4上编译它,而且由于并行化,我期望速度不会提高。但是如果我在双核AMD Opteron上编译,我会假设FORALL构造可以被利用。
或者,是否有一种方法来测量程序的有效并行化?
更新
在回答M.S.B的问题时,使用的是gfortran版本4.4.0。gfortran支持自动多线程吗?
这是值得注意的,FORALL构造已经过时了,我想,然后是什么是自动矢量化。
也许这是最好的一个单独的问题,但是自动矢量化是如何工作的?编译器是否能够检测到循环中只使用纯函数或子程序?
发布于 2010-09-20 04:22:11
如果使用,则可以使用命令行开关打开/增加填充器的详细级别,用于并行/矢量化。这样,在编译/链接期间,您将看到如下内容:
FORALL loop at line X in file Y has been vectorized我承认上一次使用它已经有几年了,所以编译器的消息看起来可能很不一样,但这是基本的想法。
发布于 2010-09-21 19:40:12
因为这是一个赋值结构,而不是循环结构。FORALL的语义状态是,在分配给左手侧(LHS)之前,对FORALL中每个赋值的右侧(RHS)表达式进行完全评估。无论RHS的操作多么复杂,包括RHS和LHS重叠的情况,都必须这样做。
大多数编译器都在为所有人进行优化,这既是因为它很难优化,也是因为它不常用。最简单的实现是简单地为RHS分配一个临时表达式,计算表达式并将其存储在临时表达式中,然后将结果复制到LHS中。分配和取消此临时分配可能会使您的代码运行得非常慢。对于编译器来说,很难自动确定什么时候可以不临时地计算RHS;大多数编译器不会尝试这样做。嵌套的DO循环更容易分析和优化。
使用一些编译器,您可以通过将FORALL封装在OpenMP "workshare“指令中,并使用启用OpenMP所需的任何标志进行编译,从而将RHS的计算并行化,如下所示:
!$omp parallel workshare
FORALL (i=,j=,...)
<assignment>
END FORALL
!$omp end parallelgfortran -fopenmp blah.f90 -o
注意,不需要兼容的OpenMP实现(至少包括更早版本的gfortran)来并行地评估RHS;如果实现评估RHS,就像它包含在OpenMP“单一”指令中一样,是可以接受的。还请注意,“工作分担”很可能不会消除RHS临时分配的内容。例如,在Mac上的IBM编译器的旧版本就是如此。
发布于 2010-09-05 23:10:02
最好的方法是测量计算的时钟时间。尝试使用和不使用并行代码。如果时钟时间减少,那么您的并行代码就可以工作了。在代码块之前和之后调用的Fortran内部system_clock将给您时钟时间。内部cpu_time将为您提供cpu时间,由于开销的原因,在运行多线程代码时,这一时间可能会上升。
知识并不像人们在语言中所认为的那样有用--它更像是一种初始化结构。编译器同样擅长优化正则循环。
Fortran编译器在没有显式指定的情况下实现真正的并行处理的能力不同,例如使用OpenMP或MPI。你在使用什么编译器?
为了获得自动多线程,我使用了ifort。手动地,我使用了OpenMP。有了这两种方法,您就可以编译有并行化和不并行化的程序,并度量差异。
https://stackoverflow.com/questions/3647872
复制相似问题