C++ 带有MPI的Scatterv/Gatherv返回一个大向量

C++ 带有MPI的Scatterv/Gatherv返回一个大向量,c++,parallel-processing,mpi,C++,Parallel Processing,Mpi,我是MPI新手,我的任务是使用它来计算一个非常大的L*m矩阵,作为更大代码体的一部分。我们从0迭代到L,执行一些计算,并将M值保存到结果矩阵中。L上每次迭代的结果都是相互独立的,这是我代码中最大的时间瓶颈,所以并行化似乎是一个合理的选择 我尝试并行化的代码可以归结为: //preceding code int M = 12; for (int i = 0; i < L; i++) //START OF PARALLEL CHUNK { funkystuffresults = do

我是MPI新手,我的任务是使用它来计算一个非常大的L*m矩阵,作为更大代码体的一部分。我们从0迭代到L,执行一些计算,并将M值保存到结果矩阵中。L上每次迭代的结果都是相互独立的,这是我代码中最大的时间瓶颈,所以并行化似乎是一个合理的选择

我尝试并行化的代码可以归结为:

//preceding code

int M = 12;
for (int i = 0; i < L; i++) //START OF PARALLEL CHUNK
{
    funkystuffresults = dosomefunkystuff(i);

    for (int j = 0; j < M; j++)
    {
        resultmatrix[i*M + j] = funkystuffresults
    }
}//END OF PARALLEL CHUNK
//前面的代码
int M=12;
for(int i=0;i
由于这段代码前面的代码的性质,我无法在运行前确定L的值,并且几乎可以肯定它不能被进程的数量清楚地划分。根据我的研究,在我看来,MPI_Scatterv是这里使用的理想函数

我最初尝试使用此代码:

    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    int sendcounts[world_size];
    int displs[world_size];
    vector<int> rec_buf(L);
    int rem = L%world_size;
    int counttester = 0;
    for (int i = 0; i < world_size; i++)
    {
        sendcounts[i] = L/world_size;
        if (rem > 0)
        {
            sendcounts[i]++;
            rem--;
        }
        displs[i] = counttester;
        counttester += sendcounts[i];
    }
    vector<int> paralleli(L);
    for (int i = 0; i < L; i++)
    {
        paralleli[i] = i;
    }
    MPI_Scatterv(&paralleli, sendcounts, displs, MPI_INT, &rec_buf, L, MPI_INT, 0, MPI_COMM_WORLD);
    for (int i = 0; i < sendcounts[world_rank]; i++) //START OF PARALLEL CHUNK
    {
         //previously mentioned code
    }
MPI通信大小(MPI通信世界和世界大小);
MPI通信等级(MPI通信世界级和世界级);
int sendcounts[世界大小];
int显示[世界大小];
向量rec_buf(L);
int rem=L%世界尺寸;
int counttester=0;
对于(int i=0;i0)
{
发送计数[i]++;
雷姆--;
}
disfs[i]=计数测试仪;
counttester+=发送计数[i];
}
向量并行i(L);
对于(int i=0;i

这对我来说似乎非常笨拙,因为我认为这是一种非常常见的问题。要使用这段代码,需要大量修改代码中的“时髦的东西”,所以我希望有更好的方法。使用scatterv(以及之后使用gatherv)是否理想?我希望使用一个即使不使用并行化也能工作的实现

作为旁注,您是否发现MPI中的任何内容是“可使用的”?MPI定义良好,可以工作,但大多数库都基于C风格的api,因此“笨拙”是一件常见的事情,我通常做的第一件事就是尽可能多地包装和隐藏MPI设置和调用。。(并不是说我做了很多次……也许十次……那是很久以前的事了)。因为这是一个常见的事情,我会搜索一些C++包装。经过这么多年的时间,在lambda/etc最终被引入之后,制作一套基于lambda的类型安全包装器应该非常简单,我希望已经有人这么做了。我已经看到了许多使用MPI的示例(大多数使用bcast和reduce,而不是散射和聚集),表面上看起来非常简单。我对MPI是全新的,虽然我承认没有太多的经验与期望。只是FI:似乎人们实际上在做某事或-但认为这是一个旁注,而不是回答。如果您的任务是“使用MPI”,我实际上怀疑您是否可以使用它们。而且前者看起来比你现在看到的要复杂一些,哦,我不确定你能不能
MPI\u Scatterv(¶lleli,&rec\u buf,…)
MPI_Scatterv(¶lleli[0],…,&rec_buf[0],…)
肯定会起作用。我不精通C++,但是基于前面的答案,<代码> MPIIsStORTEV(并行,数据(…),…,ReCiBuff.DATA(…))……/CUT>可能会有诀窍。作为一个旁注,你可以分配一个更小的<代码> ReCiBuf < /Cord>。最大大小为
rem+1
L
在此不必要地大)