【发布时间】:2014-06-15 19:42:06
【问题描述】:
我有一个类似于下面的程序。在下面的代码中,所有进程都知道所有其他进程的当前迭代步骤。但是,我很好奇是否有一种方法可以在没有诸如 MPI_PUT 之类的集体调用的情况下做到这一点,尤其是在每个进程以不同速率迭代的情况下。
#include <errno.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
/* OUTPUT
* $ mpirun -np 4 so00.exe
* @[0]: p | 0 1 2 3
* @[0]: p | 4 5 6 7
* @[0]: p | 8 9 10 11
* @[0]: p | 12 13 14 15
* @[0]: p | 16 17 18 19
* @[1]: p | 0 1 2 3
* @[1]: p | 4 5 6 7
* @[1]: p | 8 9 10 11
* @[1]: p | 12 13 14 15
* @[1]: p | 16 17 18 19
* @[2]: p | 0 1 2 3
* @[2]: p | 4 5 6 7
* @[2]: p | 8 9 10 11
* @[2]: p | 12 13 14 15
* @[2]: p | 16 17 18 19
* @[3]: p | 0 1 2 3
* @[3]: p | 4 5 6 7
* @[3]: p | 8 9 10 11
* @[3]: p | 12 13 14 15
* @[3]: p | 16 17 18 19
*/
int main(int argc, char *argv[])
{
int i, n, rank, np;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &np);
////////////////////////////////////////////////////////////////////////////
int *pos;
MPI_Win win;
MPI_Alloc_mem(sizeof(int)*np, MPI_INFO_NULL, &pos);
MPI_Win_create(pos, np, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
for (i=rank; i<(np*5); i+=np)
{
MPI_Win_fence(MPI_MODE_NOPRECEDE, win);
for (n = 0; n < np; n++)
{
MPI_Put(&i, 1, MPI_INT, n, rank, 1, MPI_INT, win);
}
MPI_Win_fence((MPI_MODE_NOSTORE | MPI_MODE_NOSUCCEED), win);
printf("@[%d]: p | ", rank);
for (n = 0; n < np; n++) printf("\t%d", pos[n]);
printf("\n");
}
////////////////////////////////////////////////////////////////////////////
MPI_Win_free(&win);
MPI_Free_mem(pos);
MPI_Finalize();
return EXIT_SUCCESS;
}
【问题讨论】:
-
MPI_Put 不是集体调用。
-
啊,我想我把它和 MPI_Win_fence 搞混了...
-
在使用 RMA 调用之前,您无法避免 MPI_Win_fence。它是一个要求。您可以通过将栅栏移出外部 for 循环来优化代码。现在的方式,NOPRECEDE 和 NOSUCCEED 在当前位置是不合适的。
-
非常感谢您的帮助。我将栅栏移到了循环之外,得到了如下数字:
@[0]: p | -1698087256 32723 -1698087256 32723 32。我用这篇文章stackoverflow.com/questions/6612421/… 中的解决方案解决了这种情况。不过,我很好奇是否还有其他方法可以使用 RMA 或其他技巧来做到这一点。再次感谢。 -
如果我将进程放在一个单独的 MPI 组中,有没有办法修改窗口、组或通信器句柄或所有它们,这样,当一个完成循环时,它会删除本身来自与窗口关联的组??
标签: c asynchronous mpi