我正在尝试制作高效的 CFD 编程复杂性来解决燃烧问题。我已经写完了实现数学模型的core,现在我关心的是代码性能。燃烧问题在计算上非常昂贵,毫无疑问我必须对我的代码进行并行化,但现在我想制作高效的串行代码,将其用作并行程序的基础。
例如,程序中有一个简化版本:
我有时间循环所在的主程序。
PROGRAM Flame
USE Geometry
CALL ALLOCATION <- Procedure there memory is allocated for X array
DO while ...
Time=Time + TH
CALL CALCULATIONS
END DO
END PROGRAM
具有所有全局变量声明的模块
MODULE Geometry
double precision , allocatable :: X(:) <-- one dimensional array for computational grid.
integer, dimension(NTR) :: KDIF <-- has a mean of pointers on some variable in cell (pressure for example)
END MODULE
用于计算和数据处理的子程序。
SUBROUTINE CALCULATIONS
USE Geometry
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
IJK = 0
DO I=1,NX <- number of cells in one dimension (such cycles for all dimensions)
DO I1=1,NTR
X(IJK+KDIF(I1)) = ... some floating-point operations <-- Possible hot spot
I1 = I1+1
END DO
X(IJK+8)=X(IJK+3)-A/X(IJ+5)-(X(IJ+10)-B)*C/(D*X(IJ+5)) (for example)
IJK = IJK + NKX <-- place between two cells in
END DO
END SUBROUTINE
程序中有更多的子程序和模块,但它们的结构都与我举的例子相似。我尝试使用 VTune Amplifier 分析我的程序,并在我在代码中指出的地方找到了一些热点。在Assembly这样的热点中,最耗时的操作一般都是moved qword;移动 ebx, dword; 等我不熟悉汇编代码,但我认为它与内存操作有关。其实我不知道如何解决这些热点。
所以有一些问题我需要澄清。这种编码风格是现代的吗?我的意思是也许我应该对此类程序使用另一种技术,例如指针、FORALL 和 WHERE 操作,它们可以更快、更节省内存、更适合 CFD 问题?这样的程序结构是否有效(数据模块、子程序、可分配数组、一维数组甚至对于多维问题)?
提前感谢您的关注、回答和建议。