使用MPI的c ++代码中每个进程的相同随机数

时间:2011-06-10 01:50:36

标签: c++ mpi

我有可用的C ++ MPI代码,因为它编译并确实在指定数量的处理器( n )上启动。问题是它只是执行相同的计算 n 次,而不是更快地进行一次 n 次计算。

我已经破解了很多我在各种网站上找到的例子,看来我错过了正确使用MPI_Send和MPI_Receive,但我找不到这些命令的实例,这些命令将函数作为输入(并且我是混淆了为什么这些MPI命令对除函数之外的任何东西都有用。)

我的代码如下。本质上它调用了我编写的C ++函数来获得Fisher的精确测试p值。随机数位只是我用来测试速度的东西。

我想要的是这个程序要做的是用每组随机变量( A B Fisher.TwoTailed >, C D )到不同的处理器,而不是在多个处理器上进行完全相同的计算。提前感谢您的任何见解 - 干杯!

以下是代码:

int 
main (int argc, char* argv[]) 
{ 

  int id;
  int p;
//
//  Initialize MPI.
//
  MPI::Init ( argc, argv );
//
//  Get the number of processors.
//
  p = MPI::COMM_WORLD.Get_size ( );
//
//  Get the rank of this processor.
//
 id = MPI::COMM_WORLD.Get_rank ( );

  FishersExactTest Fishers;

  int i = 0;
  while (i < 10) {
    int A = 0 + rand() % (100 - 0);
    int B = 0 + rand() % (100 - 0);
    int C = 0 + rand() % (100 - 0);
    int D = 0 + rand() % (100 - 0); 
    cout << Fishers.TwoTailed(A, B, C, D) << endl;
    i += 1;
  }

  MPI::Finalize ( );
  return 0;
}

4 个答案:

答案 0 :(得分:3)

您应该参考一些关于并行计算和MPI的基础培训。一个教会我基础知识的好资源是a free set of online courses put up by the National Center for Supercomputing Applications (NCSA)

答案 1 :(得分:3)

你必须告诉MPI如何并行化代码 - 它不会自动执行。

换句话说,您无法在所有系统上初始化MPI,然后将它们传递给相同的循环。您希望使用每个处理器的id来确定它将在哪个循环部分工作。然后你需要它们将结果全部传递回ID 0。

答案 2 :(得分:3)

以上所有答案都是完全正确的。我来补充一点:

在这里,由于看起来你只是在进行随机抽样,所以你需要做的就是让不同的处理器生成不同的随机数给Fishers.TwoTailed是为了确保它们都有不同的PRNG种子:

int 
main (int argc, char* argv[]) 
{ 

  int id;
  int p;
//
//  Initialize MPI.
//
  MPI::Init ( argc, argv );
//
//  Get the number of processors.
//
  p = MPI::COMM_WORLD.Get_size ( );
//
//  Get the rank of this processor.
//
 id = MPI::COMM_WORLD.Get_rank ( );

  FishersExactTest Fishers;

  srand(id);  // <--- each rank gets a different seed

  int i = 0;
  while (i < 10) {
    int A = 0 + rand() % (100 - 0);
    int B = 0 + rand() % (100 - 0);
    int C = 0 + rand() % (100 - 0);
    int D = 0 + rand() % (100 - 0); 
    cout << Fishers.TwoTailed(A, B, C, D) << endl;
    i += 1;
  }

  MPI::Finalize ( );
  return 0;
}

因为循环是1..10,你仍然可以让每个进程完成10个样本。如果你希望他们做 10,你可以将p除以p并做一些事情来分配余数:例如

int niters = (10+id)/p;
int i=0;
while (i < niters) {
  ...
}

答案 3 :(得分:0)

那么,当你运行MPI工作时会得到什么消息?只是重申其他人所说的,你必须明确定义每个处理器的工作是什么......例如..如果你是0级(默认),那么这样做...如果你是等级1那么..(或其他语法)定义每个等级的角色。然后,根据您构建代码的方式,您可以拥有节点Send / Recv,Gather,Scatter等。