我正在用MPI编写Mergesort来排序整数数组。这个想法是将数组的左半部分合并到相同的等级,同时将数组的右半部分发送到子等级。所以,如果有四个过程,它看起来像这样:
rank 0, a[0..N]
/ \
rank 0, a[0..N/2] rank1, a[N/2..N]
/ \ / \
rank0, a[0..N/4] rank2,a[N/4..N/2] rank1,a[N/2..3N/4] rank3,a[3N/4..N]
父级别总是将未排序的数组右半部分发送给右子级,从右子级接收已排序的子数组。
在串行合并算法算法中,子阵列的排序可以在整个阵列的同一地址上完成,而不会生成临时数组。使用MPI_Send
和MPI_Recv
可以将同样的事情应用于MPI实施吗?我的理解是MPI_Send
发送子阵列的第一个元素的地址
//rank == 0
int *a, size1, size2;
getData(a);
size1=size/2;
size2=size-size1;
MPI_Send(a+size1, size2, MPI_INT, seed_rank, DATA, MPI_COMM_WORLD);
通过执行以下操作,子进程似乎确实获得了子数组值:
//rank == 1
int *array;
array = new int(size);
MPI_Recv(array, size, MPI_INT, parent, DATA, MPI_COMM_WORLD, &status);
mergesort_parallel_mpi(array, size, level);
等级1然后将对接收的子阵列元素进行合并排序,该子阵列元素存储在与原始阵列不同的地址处。有没有办法接收数组地址,因为如果两个已排序的子数组位于同一个块中,这将更容易合并(这就是串行合并的作用)。如果我没有为1级中的新数组分配,我将收到错误。
答案 0 :(得分:1)
你似乎认为MPI进程共享内存:他们不会。子进程无法直接修改父进程,因为它们具有完全独立的内存空间(实际上可能位于物理上独立的计算机上)。
答案 1 :(得分:1)
仅当您的进程在同一台物理计算机上运行时才发送指向内存位置的指针,而在使用MPI的分布式处理中则不是这样,其中每个进程都会收到已发送到的数据的副本它。您应该将每个进程视为在单独的计算机上运行,因此它可以直接访问任何其他计算机内存。
如果您想使用共享内存和线程处理数据,请查看OpenMP API。