猿问

通过MPI发送和接收2D阵列

我要解决的问题如下:


我拥有的C ++串行代码跨一个大型2D矩阵进行计算。为了优化此过程,我希望拆分这个大型2D矩阵并使用MPI在4个节点(例如)上运行。节点之间发生的唯一通信是在每个时间步结束时共享边值。每个节点与其邻居共享边缘阵列数据A [i] [j]。


基于对MPI的了解,我可以实现以下方案。


if (myrank == 0)

{

 for (i= 0 to x)

 for (y= 0 to y)

 {

  C++ CODE IMPLEMENTATION 

  .... 

  MPI_SEND(A[x][0], A[x][1], A[x][2], Destination= 1.....)

  MPI_RECEIVE(B[0][0], B[0][1]......Sender = 1.....)

  MPI_BARRIER

}


if (myrank == 1)

{

for (i = x+1 to xx)

for (y = 0 to y)

{

 C++ CODE IMPLEMENTATION

 ....

 MPI_SEND(B[x][0], B[x][1], B[x][2], Destination= 0.....)

 MPI_RECEIVE(A[0][0], A[0][1]......Sender = 1.....)

 MPI BARRIER

}

我想知道我的方法是否正确,并且也希望对其他MPI功能的任何指导也寻求实施。

江户川乱折腾
浏览 610回答 3
3回答

慕运维8079593

只是为了扩大Joel的观点:如果分配数组以使它们连续(这样的话,C的“多维数组”不会自动给您:),则这样做会容易得多。int **alloc_2d_int(int rows, int cols) {&nbsp; &nbsp; int *data = (int *)malloc(rows*cols*sizeof(int));&nbsp; &nbsp; int **array= (int **)malloc(rows*sizeof(int*));&nbsp; &nbsp; for (int i=0; i<rows; i++)&nbsp; &nbsp; &nbsp; &nbsp; array[i] = &(data[cols*i]);&nbsp; &nbsp; return array;}/*...*/int **A;/*...*/A = alloc_2d_init(N,M);然后,您可以使用以下命令发送和接收整个NxM阵列MPI_Send(&(A[0][0]), N*M, MPI_INT, destination, tag, MPI_COMM_WORLD);完成后,释放内存free(A[0]);free(A);另外,MPI_Recv是阻止接收,并且MPI_Send可以是阻止发送。根据Joel的观点,一件事意味着您绝对不需要障碍。此外,这意味着,如果您具有上述的发送/接收模式,则可能陷入僵局-每个人都在发送,没有人在接收。更安全的是:if (myrank == 0) {&nbsp; &nbsp;MPI_Send(&(A[0][0]), N*M, MPI_INT, 1, tagA, MPI_COMM_WORLD);&nbsp; &nbsp;MPI_Recv(&(B[0][0]), N*M, MPI_INT, 1, tagB, MPI_COMM_WORLD, &status);} else if (myrank == 1) {&nbsp; &nbsp;MPI_Recv(&(A[0][0]), N*M, MPI_INT, 0, tagA, MPI_COMM_WORLD, &status);&nbsp; &nbsp;MPI_Send(&(B[0][0]), N*M, MPI_INT, 0, tagB, MPI_COMM_WORLD);}另一种更通用的方法是使用MPI_Sendrecv:int *sendptr, *recvptr;int neigh = MPI_PROC_NULL;if (myrank == 0) {&nbsp; &nbsp;sendptr = &(A[0][0]);&nbsp; &nbsp;recvptr = &(B[0][0]);&nbsp; &nbsp;neigh = 1;} else {&nbsp; &nbsp;sendptr = &(B[0][0]);&nbsp; &nbsp;recvptr = &(A[0][0]);&nbsp; &nbsp;neigh = 0;}MPI_Sendrecv(sendptr, N*M, MPI_INT, neigh, tagA, recvptr, N*M, MPI_INT, neigh, tagB, MPI_COMM_WORLD, &status);或非阻塞发送和/或接收。

至尊宝的传说

首先,您不需要那么多的障碍。其次,您应该真正将数据作为单个块发送,因为多次发送/接收阻止它们会导致性能下降。

千万里不及你

C的多维数组是一个连续的内存块;如果您分配double d[50][50];,那是一个连续的内存块。处理动态分配的“伪2D”数组的一种方法是分配一个指针块和一组单独的(通常是不连续的)存储块,每行一个。
随时随地看视频慕课网APP
我要回答