为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
江户川乱折腾 2019-10-31 13:06:13
我要解决的问题如下:我拥有的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功能的任何指导也寻求实施。
查看完整描述

3 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

只是为了扩大Joel的观点:


如果分配数组以使它们连续(这样的话,C的“多维数组”不会自动给您:),则这样做会容易得多。


int **alloc_2d_int(int rows, int cols) {

    int *data = (int *)malloc(rows*cols*sizeof(int));

    int **array= (int **)malloc(rows*sizeof(int*));

    for (int i=0; i<rows; i++)

        array[i] = &(data[cols*i]);


    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) {

   MPI_Send(&(A[0][0]), N*M, MPI_INT, 1, tagA, MPI_COMM_WORLD);

   MPI_Recv(&(B[0][0]), N*M, MPI_INT, 1, tagB, MPI_COMM_WORLD, &status);

} else if (myrank == 1) {

   MPI_Recv(&(A[0][0]), N*M, MPI_INT, 0, tagA, MPI_COMM_WORLD, &status);

   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) {

   sendptr = &(A[0][0]);

   recvptr = &(B[0][0]);

   neigh = 1;

} else {

   sendptr = &(B[0][0]);

   recvptr = &(A[0][0]);

   neigh = 0;

}

MPI_Sendrecv(sendptr, N*M, MPI_INT, neigh, tagA, recvptr, N*M, MPI_INT, neigh, tagB, MPI_COMM_WORLD, &status);

或非阻塞发送和/或接收。


查看完整回答
反对 回复 2019-10-31
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

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


查看完整回答
反对 回复 2019-10-31
?
千万里不及你

TA贡献1784条经验 获得超9个赞

C的多维数组是一个连续的内存块;如果您分配double d[50][50];,那是一个连续的内存块。处理动态分配的“伪2D”数组的一种方法是分配一个指针块和一组单独的(通常是不连续的)存储块,每行一个。

查看完整回答
反对 回复 2019-10-31
  • 3 回答
  • 0 关注
  • 609 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信