【发布时间】:2019-12-30 05:08:44
【问题描述】:
我已经远离并行编程很长一段时间了,我正在尝试找出在具有复杂依赖结构的许多处理器之间协调发送大量数据的最佳方法。例如,我可能会向/从以下进程发送数据:
int process_1_dependencies[] = {2,3,5,6}
int process_2_dependencies[] = {1}
int process_3_dependencies[] = {1,4,5}
int process_4_dependencies[] = {3,5,6}
int process_5_dependencies[] = {1,3,4,6}
int process_6_dependencies[] = {1,4,5,7}
int process_7_dependencies[] = {6,8}
int process_8_dependencies[] = {7}
显而易见且愚蠢的做法是:
for(int i = 0; i < world_size; i++)
{
for(int j = 0; j < dependency_length; j++)
{
if (i == my_rank)
{
mpi_irecv(...,source=dependency[j],)
}
else
{
if (i == dependency[j])
{
mpi_isend(...,dest=dependency[j])
}
}
}
// blocking stuff?
}
我实际上不确定这是否会在您进行 100 次通信后起作用,无论如何,它似乎效率极低。它至少是 O(N) 并且只允许一次接收单个进程。更好的方法是使用阻塞并确保独立进程同时交换信息。但这变得相当复杂,需要优化哪些进程同时发送和接收。
我是不是完全想多了?这样做是否安全(假设每个发送进程都有一个接收对):
for(int i = 0; i < dependency_length; i++)
{
mpi_isend(..., dest=dependency[i], ...)
mpi_irecv(..., source=dependency[i], ...)
}
//blocking stuff
抱歉,问题没有重点。我不在我的电脑旁,所以我无法真正测试它,即使它测试了,我想我也不确定它是否可销售,并且缓冲区将继续为任意数量的进程工作?
【问题讨论】:
-
除非您能找到一种最佳的和无死锁方式来使用阻塞操作,否则您宁愿简单地将非阻塞请求和
MPI_Waitall()排队。另一种选择是使用 MPI 拓扑和MPI_Neighbor_alltoall()。如果这是合适的,它会更优雅,但我不能保证实现会比手动使用非阻塞操作更有效。