理想情况下,幽灵细胞应该与您的内存块位于同一内存块中。normal细胞。这样,您就可以保持寻址方案简单。在该方案中,图像由多个完整行分布,使用MPI_Scatter
and MPI_Gather
。在非边界排名中,您为另外两个幽灵行分配足够的内存:
height = total_hight / ranks;
std::vector<float> data(width * (height + 2));
float* image = &data[width];
float* ghost_north = &data[0]
float* ghost_south = &data[width * (height + 1)]
float* inner_north = image;
float* inner_south = &image[width * (height - 1)]
MPI_Scatter(root_image, width * height, MPI_FLOAT,
image, width * height, MPI_FLOAT, ...);
...
iterations {
MPI_SendRecv(inner_north, width, MPI_FLOAT, north, tag,
ghost_north, width, MPI_FLOAT, north, tag, ...)
MPI_SendRecv(inner_south, width, MPI_FLOAT, south, tag,
ghost_south, width, MPI_FLOAT, south, tag, ...)
... compute ...
}
MPI_Gather(image, width * height, MPI_FLOAT,
root_image, width * height, MPI_FLOAT, ...);
该伪代码不考虑特殊的边界情况。
简单的一维分割的问题是通信成本和额外的光环数据不是最佳的。特别是对于较小的图像和较大数量的参与行列。
这是一个Rolf Rabenseifner 的优秀例子 https://fs.hlrs.de/projects/par/par_prog_ws/pdf/heat_mpi_2.pdf关于 MPI 的数据分解和 halo 通信方法。他还解释了如何改进沟通方法。对于 2D 分解,您将需要派生 MPI 数据类型用于初始通信和垂直边界。