C++基于MPI实现GameOfLife(生命游戏)的进程任务划分问题
MPI并行实现生命游戏问题解答
核心疑问解答
- 接收到任务分片后仅遍历自身持有的子数组完成计算即可,不需要访问完整原数组。并行设计的核心就是拆分任务后每个进程仅持有自己负责的网格分片,其他进程不会也不需要存储全量网格数据。你需要给自己的子数组额外开辟上下2行幽灵边界空间,用来存储上下邻居进程发来的边界行数据,计算自身分片内的细胞状态时,直接访问本地子数组(包括幽灵边界)的内容即可,不需要跨进程访问全局数据。
- 计算完成后仅需要将自身负责的新子数组(不包含幽灵边界)发回根进程即可,不需要发送完整数组。全量数组只有根进程需要用来打印和迭代分发,其余进程发送全量数组只会造成不必要的带宽浪费,根进程接收完全部子分片后按进程顺序拼接即可得到完整的新一代网格。
现有代码问题修正提示
- 根进程逻辑问题:你在处理剩余行的分支中重复定义了
left_elements变量,且填充send_array的逻辑只适配了固定elements_per_process长度的分片,剩余行对应的内容没有正确填充到send_array就发送给了最后一个进程,会导致最后一个进程收到无效数据。 - 非根进程逻辑问题:
- 你将根进程发来的分片存在
recieved_array中,但后续发送边界行、计算邻居用的是currentWorld数组,两个数组没有做数据同步,所有读取操作都会拿到无效值。 - 循环逻辑存在明显语法错误:列循环的终止条件写为
i<COLS,邻居计算的列遍历范围固定为j+1,完全没有覆盖8个邻居的坐标范围,边界判断引用的是全局ROWS而非本地子数组的行长度,会导致大量越界访问和计算错误。 - 邻居计算的坐标判断逻辑冗余,不需要针对左右边界做特殊分支,只需要给左右边界也加环形偏移判断即可。
- 你将根进程发来的分片存在
学习参考建议
可优先掌握MPI基础聚集通信原语MPI_Scatter、MPI_Gather的用法,替代你当前手写的循环发送/接收分片逻辑,能大幅降低代码出错概率;另外分布式网格计算的幽灵边界设计是通用范式,相关内容在国内多数高校的《并行计算》教材中都有详细讲解。
内容的提问来源于stack exchange,提问作者Mahmoud
相关产品推荐
相关产品推荐

