使用boost MPI并行化循环

时间:2015-02-27 06:06:03

标签: mpi

我正在学习使用Boost.MPI来并行化大量的计算,下面是我的简单测试,看看我是否能正确获得MPI逻辑。但是,我没有让它工作。我使用了world.size()= 10,数据数组中共有50个元素,每个进程都会进行5次迭代。我希望通过让每个进程将更新的数据数组发送到根进程来更新数据数组,然后根进程接收更新的数据数组然后打印出来。但我只更新了一些元素。

感谢您的帮助。

#include <boost/mpi.hpp>
#include <iostream>
#include <cstdlib>

namespace mpi = boost::mpi;
using namespace std;

#define max_rows 100
int data[max_rows];

int modifyArr(const int index, const int arr[]) {
  return arr[index]*2+1;
}

int main(int argc, char* argv[])
{
  mpi::environment env(argc, argv);
  mpi::communicator world;

  int num_rows = 50;
  int my_number;

  if (world.rank() == 0) {
    for ( int i = 0; i < num_rows; i++)
        data[i] = i + 1;
  }

  broadcast(world, data, 0);

  for (int i = world.rank(); i < num_rows; i += world.size()) {
    my_number = modifyArr(i, data);
    data[i]   = my_number;

    world.send(0, 1, data);

    //cout << "i=" << i << " my_number=" << my_number << endl;

    if (world.rank() == 0)
      for (int j = 1; j < world.size(); j++) 
        mpi::status s = world.recv(boost::mpi::any_source, 1, data);
  }

  if (world.rank() == 0) {
    for ( int i = 0; i < num_rows; i++)
      cout << "i=" << i << " results = " << data[i] << endl;
  }

  return 0;
}

1 个答案:

答案 0 :(得分:1)

你的问题可能就在这里:

mpi::status s = world.recv(boost::mpi::any_source, 1, data);

这是数据返回主节点的唯一方法。

但是,您没有告诉主节点data中哪里存储了它所获得的答案。由于数据是数组的地址,因此所有内容都应存储在第0个元素中。

交错在每个节点上处理的数组元素是一个非常糟糕的主意。您应该为每个节点分配数组块,以便您可以一次发送数组的整个块。这将大大减少通信开销。

此外,如果你的问题只是加速循环,你应该考虑OpenMP,它可以做这样的事情:

#pragma omp parallel for
for(int i=0;i<100;i++)
  data[i]*=4;

的Bam!我只是将它分开,以便在我的所有进程之间进行循环,而无需进一步的工作。