c - 创建优化的总和缩减



我刚刚开始学习 HPC 课程,正在做一项作业,我们希望实现相当于MPI_SUM MPI_Reduce的 Reduce 函数......够容易吧?这是我所做的:

我从将数据/数组从所有节点发送到根节点(排名第 0 的进程)的基本概念开始,在那里我计算了总和。

作为第二步,我进一步优化了它,以便每个进程将数据发送到计算总和的镜像,并且此过程不断重复,直到最终结果出现在根节点(第 0 个进程)中。我的实现如下:

for(k=(size-1); k>0; k/=2)
{
if(rank<=k)
{
if(rank<=(k/2))
{
//receiving the buffers from different processes and computing them
MPI_Recv(rec_buffer, count, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for(i=0; i<count; i++)
{
res[i] += rec_buffer[i];
}
}
else
{
MPI_Send(res, count, MPI_INT, k-rank, 0, MPI_COMM_WORLD);
}
}
}

但问题是,与MPI_Reduce函数本身相比,这段代码的性能要差得多。

那么如何进一步优化呢?如果更好,我能做些什么不同的事情来制作?我无法使总和循环成为多线程,因为我们需要在单个线程中执行此操作。我可以优化总和循环,但不确定如何以及从哪里开始。

对于一个非常基本的问题,我深表歉意,但我真的开始涉足HPC领域。谢谢!

第二种方法是正确的,因为您执行相同数量的通信,但已并行化了reduce操作(在您的情况下为总和)和通信(因为您在子集之间进行通信)。您通常会执行 reduce 操作,如 Reduce 运算符中所述。

但是,您可能希望尝试使用 MPI_Isend 和 MPI_Irecv 进行异步通信,以提高性能并更接近MPI_Reduce性能。

@GillesGouillardet提供了一个实现,你可以看到代码中的通信是用isend和irecv完成的(查找"MCA_PML_CALL(isend"和"MCA_PML_CALL(irecv")

最新更新