创建优化的总和减少量

时间:2018-03-25 07:35:01

标签: c arrays algorithm bigdata mpi

我刚刚开始参加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函数本身相比表现得更差。

那么我该如何进一步优化呢?如果做得更好,我可以做些什么?我不能使sum循环多线程,因为我们需要在单个线程中执行它。我可以优化总和循环,但不知道如何以及从何处开始。

我为一个非常基本的问题道歉,但我真的开始在HPC领域受到影响。谢谢!

1 个答案:

答案 0 :(得分:1)

您的第二种方法是正确的方法,因为您进行了相同数量的通信,但是已将化简操作(在您的情况下为和)与通信(因为在子集之间进行通信)并行化。您通常会像Reduction operator中所述减少操作。

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

@GillesGouillardet提供了一个实现,您可以看到代码中的通信是通过isend和irecv完成的(请查找“ MCA_PML_CALL(isend”和“ MCA_PML_CALL(irecv”))