MPI:如何启动三个将在不同线程中执行的函数

Posted

技术标签:

【中文标题】MPI:如何启动三个将在不同线程中执行的函数【英文标题】:MPI: How to start three functions which will be executed in different threads 【发布时间】:2012-10-18 00:26:27 【问题描述】:

我有 3 个功能和 4 个核心。我想使用 MPI 和 C++ 在新线程中执行每个函数 我写这个

int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
size--;
if (rank == 0)

    Thread1();

else 

    if(rank == 1)
    
        Thread2();
    
    else
    
        Thread3();
    

MPI_Finalize();

但它只执行 Thread1()。我必须如何更改代码?

谢谢!

【问题讨论】:

函数 Thread1()、Thread2() 和 Thread3() 的作用是什么? 简单的数学运算和显示结果 MPI 在各自独立的地址空间中创建多个进程,而不是线程。您使用的是什么 MPI 版本? Microsoft MPI 存在控制台重定向问题,因此您可能看不到来自 0 以外的等级的输出。 【参考方案1】:

打印以筛选变量size 的当前值(可能不递减它),您将找到1。即:“有1进程正在运行”。

您可能以错误的方式运行编译后的代码。考虑使用 mpirun(或 mpiexec,取决于您的 MPI 实现)来执行它,即

 mpirun -np 4 ./MyCompiledCode

-np 参数指定您将启动的进程数(这样做,您的MPI_Comm_size 将如您预期的那样为 4)。


但目前,由于 C++,您没有明确使用任何东西。您可以考虑一些 MPI 的 C++ 绑定,例如Boost.MPI


我在您提供的code 上做了一些工作。我对其进行了一些更改,以生成 this working mpi 代码(我提供了一些需要的大写字母更正)。

仅供参考:

编译(gcc、mpich下):

 $ mpicxx -c mpi1.cpp 
 $ mpicxx -o mpi1 mpi1.o

执行

$ mpirun -np 4 ./mpi1

输出

size is 4
size is 4
size is 4
2 function started.
thread2
3 function started.
thread3
3 function ended.
2 function ended.
size is 4
1 function started.
thread1
1 function ended.

请注意,stdout 很可能被搞砸了。

您确定以正确的方式编译代码吗?

【讨论】:

我没有 mpirun ,但我有 mpiexec。我从 cmd 运行我的应用程序:mpiexec -np 4 ./MyApp.exe 但是在 cmd 上我只看到 MPI 函数之前的代码结果。并且 MPI 函数不起作用。 @A.N.R.I..请考虑我的问题。顺便说一句,您为什么不考虑共享内存多线程(例如 openMP)? @A.N.R.I 没有std::cout <<size; 工作?将其放入if (rank == 0) 部分。代码是否显示任何内容?通常使用 MPI 和 stdout 会出现问题。 @A.N.R.I, btw mpi_init 应该放在函数的最顶部。其次,我会将数学与多线程分离。 IE。尝试使用函数Thread 的一些表达式,在不同的文本文件上输出。通过这种方式,您将了解多线程是否正常工作。然后把数学放进去。 我将代码更改为srcboard.com/yfa2e28,它可以正常工作但无与伦比。也许我在某处上传了 VS2010 项目?很容易看到我的项目【参考方案2】:

您的问题是 MPI 无法将控制台输入提供给许多进程,而只能提供给等级为 0 的进程。因为main的前三行:

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

    int oper;
    std::cout << "Enter Size:";
    std::cin >> oper;           // <------- The problem is right here

    Operations* operations = new Operations(oper);
    int rank, size;
    MPI_Init(&argc, &argv);
    int tid;
    MPI_Comm_rank(MPI_COMM_WORLD, &tid);
    switch(tid)
    

所有进程,但排名0 块等待他们无法获得的控制台输入。您应该重写main 函数的开头,如下所示:

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

    int oper;

    MPI_Init(&argc, &argv);
    int tid;
    MPI_Comm_rank(MPI_COMM_WORLD, &tid);

    if (tid == 0) 
       std::cout << "Enter Size:";
       std::cin >> oper;
    
    MPI_Bcast(&oper, 1, MPI_INT, 0, MPI_COMM_WORLD);

    Operations* operations = new Operations(oper);
    switch(tid)
    

它的工作原理如下:只有rank 0 显示提示,然后将控制台输入读入oper。然后从等级0 广播oper 的值,以便所有其他进程获得正确的值,创建Operations 对象,然后分支到适当的函数。

【讨论】:

以上是关于MPI:如何启动三个将在不同线程中执行的函数的主要内容,如果未能解决你的问题,请参考以下文章

启动多个线程并重新启动它们

java如何检查执行的线程已卡死

MPI +线程并行化与仅MPI的优势(如果有的话)是什么?

线程中阻塞 MPI_Recv 的 CPU 使用率

在不同的线程中执行 lambda 函数

在混合 MPI/OpenMP 中进行 MPI 调用的线程