我有可用的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;
}
答案 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等。