对于较大的计算域,考虑对物理流域进行分块,并以0作为根进程进行输入输出等操作。
对于一个LBM的单线程程序,需要作以下修改
1、原来所有变量都可以继承为当前线程变量,但需要增加收集所有计算域的数组变量;
2、数据操作更新过程仅发生节点本地的子程序不需要进行数据传输,只有在收集所有流域数据时才需要数据分享;
3、认真查找哪些子程序需要进行数据传输。对于最简单的LBM程序仅Propagation步需要,但当程序需要计算变量梯度时、或者需要进行格式差分时,同样需要数据传输;(在LBM中,这样的传输是有方向的,有必要使用next子函数来简化程序形式,标明非本地操作)。
4、对于LBM中的Propagation过程来讲,由于分块断裂而需要进行的数据传输,传输的接收可以直接存放到目标方向上来代替原来的值(传输前本来就没有值);但是对于需要相邻点的数据计算梯度变量时或者需要计算格式差分时,就必须在外层增加一套虚拟网格进行数据传输。
例如在分块断裂的边界上有点A,其右上左下的相邻点分别为A1,A2,A3,A4,A1在另一个线程块。若计算A点的物理量rho需要临近的四个点的值,那么A4的值在另一线程块中,传输过来的值,不能直接存储在A中,一是A的值要用来计算A3的值,而是A的更新需要计算后再存储。因此最好考虑增加一层虚拟边界,对于边界点不受影响,因为要对边界做单独处理,但是对于分块断裂的点是有影响的。
5、单线程程序中,对边界上物理量进行的分类操作的都需要重写,因为分块后,这些边界被打断,不同线程描述边界的方法不再适用。 可以考虑用walls函数来实现统一。
6、基于全局考虑的一些判断条件或变换,需要进行调整。
另:
1. MPI_BCAST, MPI_GATHER等组操作语句不能只在单线程中运行;
2. 用串行程序对并行程序进行单步调试非常有效;
3. 写小程序对分析非常有效,如对串行并行计算结果进行比较,如数据传输/合并模型测试。
网友评论