gpt4 book ai didi

c - MPI - 进程之间的通信不良

转载 作者:行者123 更新时间:2023-11-30 14:44:31 26 4
gpt4 key购买 nike

我正在尝试在进程之间传递频率 vector 并在进程中更新它。进程以树形拓扑进行通信:

0: 1 2
1: 0 3 4 5 6
2: 0 7 8
3: 1
4: 1 9 10
5: 1
6: 1
7: 2
8: 2 11
9: 4
10: 4
11: 8

基本上,等级 0 只能与等级 1 和等级 2 通信,等级 1 只能与等级 0、3、4、5、6 等通信。最后,Rank 0 应该有一个包含其他Rank 的所有值的频率 vector 。

if (rank == 0) {
for (i = 0; i < nr_elements; i++) {
MPI_Recv(local_frequency, num_alphabets, MPI_INT, neigh[i], 0, MPI_COMM_WORLD, &status);
printf("[RANK %d]Received from %d\n", rank, neigh[i]);
for(i = 0; i < num_alphabets; i++) {
frequency[i]+=local_frequency[i];
}
}

}

else {
//leaf
if (nr_elements == 1) {
MPI_Send(frequency, num_alphabets, MPI_INT, parent, 0, MPI_COMM_WORLD);
printf("[RANK %d]Sent to %d\n", rank, parent);
}
else {
//first we receive
for (i = 0; i < nr_elements; i++) {
if (neigh[i] != parent) {
MPI_Recv(local_frequency, num_alphabets, MPI_INT, neigh[i], 0, MPI_COMM_WORLD, &status);
printf("[RANK %d]Received from %d\n", rank, neigh[i]);
for(i = 0; i < num_alphabets; i++) {
frequency[i]+=local_frequency[i];
}
}
}
MPI_Send(frequency, num_alphabets, MPI_INT, parent, 0, MPI_COMM_WORLD);
printf("[RANK %d]Sent to %d\n", rank, parent);
}

这是他们沟通的结果:

 - [RANK 2]Received from 7                                              
- [RANK 2]Sent to 0
- [RANK 3]Sent to 1
- [RANK 6]Sent to 1
- [RANK 7]Sent to 2
- [RANK 4]Received from 9
- [RANK 4]Sent to 1
- [RANK 5]Sent to 1
- [RANK 9]Sent to 4
- [RANK 0]Received from 1
- [RANK 1]Received from 3
- [RANK 1]Sent to 0
- [RANK 10]Sent to 4
- [RANK 11]Sent to 8
- [RANK 8]Received from 11
- [RANK 8]Sent to 2

每个 child 都会向其 parent 发送信息,但显然并非所有消息都会被收到。但是,如果我在每次 MPI_Recv 之后删除更新操作,一切都会正常工作。同步有问题吗?我该怎么办?

Some things you should know:
- num_alphabets = 256
- parent and nr_elements are well calculated
- neigh is the neighbours vector

最佳答案

调试

使用 -g 进行编译并在调试器中运行可能会帮助您找出问题所在。为此,您可以按如下方式启动 MPI 程序:

mpirun -n 4 xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...]

这将为每个进程打开一个终端窗口,允许您独立检查每个进程的内存和堆栈。

阻止发送/接收

由于 MPI_RecvMPI_Send 都是阻塞的,因此您很容易陷入这样一种情况:两个进程在一个进程应该从另一个进程接收数据时却正在发送数据。您可以阅读 dining philosophers以及他们的同类,以更好地处理此类情况。我还建议添加到调试输出消息中,指示您的进程何时尝试发送和尝试接收。您可能会发现一对在应该互相发送/接收的情况下都在尝试接收或都在尝试发送。

非阻塞通信

解决上述问题的方法是使用 MPI 的非阻塞发送/接收命令: MPI_IsendMPI_Irecv 。这些消除了您在上面发现的竞争条件,并且在一个进程可以在等待另一个进程的结果的同时完成工作的情况下也很方便。在您的情况下,这必然会发生,因为您有一棵树,并且无法确定哪个子节点将首先返回其结果。

关于c - MPI - 进程之间的通信不良,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53487265/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com