c - 如何通过MPI加速这个问题

标签 c mpi openmpi

(1)。我想知道如何使用 MPI 加快下面代码循环中耗时的计算?

 int main(int argc, char ** argv)   
 {   
 // some operations           
 f(size);           
 // some operations         
 return 0;   
 }   

 void f(int size)   
 {   
 // some operations          
 int i;           
 double * array =  new double [size];           
 for (i = 0; i < size; i++) // how can I use MPI to speed up this loop to compute all elements in the array?   
 {   
 array[i] = complicated_computation(); // time comsuming computation   
 }           
 // some operations using all elements in array           
 delete [] array;  
 }

如代码所示,我想在MPI并行的部分之前和之后做一些操作,但是我不知道如何指定并行部分的开始和结束。

(2) 我当前的代码使用 OpenMP 来加速计算。

 void f(int size)   
 {   
 // some operations           
 int i;           
 double * array =  new double [size];   
 omp_set_num_threads(_nb_threads);  
 #pragma omp parallel shared(array) private(i)  
 {
 #pragma omp for schedule(dynamic) nowait          
 for (i = 0; i < size; i++) // how can I use MPI to speed up this loop to compute all elements in the array?   
 {   
 array[i] = complicated_computation(); // time comsuming computation   
 }          
 } 
 // some operations using all elements in array           
 }

我想知道如果我改为使用 MPI,是否可以同时为 OpenMP 和 MPI 编写代码?如果可以,代码怎么写,怎么编译运行?

(3)我们的集群有三个版本的MPI:mvapich-1.0.1、mvapich2-1.0.3、openmpi-1.2.6。 它们的用法一样吗?特别是在我的情况下。 哪一个最适合我使用?

谢谢和问候!


更新:

关于如何指定并行部分的开始和结束的问题,我想多解释一下。在下面的玩具代码中,我想限制函数 f() 中的并行部分:

#include "mpi.h"  
#include <stdio.h>  
#include <string.h>  

void f();

int main(int argc, char **argv)  
{  
printf("%s\n", "Start running!");  
f();  
printf("%s\n", "End running!");  
return 0;  
}  


void f()  
{  
char idstr[32]; char buff[128];  
int numprocs; int myid; int i;  
MPI_Status stat;  

printf("Entering function f().\n");

MPI_Init(NULL, NULL);  
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
MPI_Comm_rank(MPI_COMM_WORLD,&myid);  

if(myid == 0)  
{  
  printf("WE have %d processors\n", numprocs);  
  for(i=1;i<numprocs;i++)  
  {  
    sprintf(buff, "Hello %d", i);  
    MPI_Send(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD); }  
    for(i=1;i<numprocs;i++)  
    {  
      MPI_Recv(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD, &stat);  
      printf("%s\n", buff);  
    }  
}  
else  
{  
  MPI_Recv(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &stat);  
  sprintf(idstr, " Processor %d ", myid);  
  strcat(buff, idstr);  
  strcat(buff, "reporting for duty\n");  
  MPI_Send(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD);  
}  
MPI_Finalize();  

printf("Leaving function f().\n");  
}  

但是,运行输出不是预期的。并行部分前后的 printf 部分已被每个进程执行,而不仅仅是主进程:

$ mpirun -np 3 ex2  
Start running!  
Entering function f().  
Start running!  
Entering function f().  
Start running!  
Entering function f().  
WE have 3 processors  
Hello 1 Processor 1 reporting for duty  

Hello 2 Processor 2 reporting for duty  

Leaving function f().  
End running!  
Leaving function f().  
End running!  
Leaving function f().  
End running!  

所以在我看来,并行部分并不仅限于 MPI_Init() 和 MPI_Finalize() 之间。

除了这个,我还希望有人能回答我的其他问题。谢谢!

最佳答案

快速编辑(因为我不知道如何发表评论,或者我还不允许发表评论)——3lectrologos 关于 MPI 程序的并行部分是不正确的。您不能在 MPI_Init 之前和 MPI_Finalize 之后执行串行工作并期望它实际上是串行的——它仍将由所有 MPI 线程执行。

我认为部分问题在于 MPI 程序的“并行部分”是整个程序。 MPI 将在大约同一时间在您指定的每个节点上开始执行相同的程序(您的主函数)。 MPI_Init 调用只是为程序设置某些东西,以便它可以正确使用 MPI 调用。

我认为您想做的事情的正确"template"(伪代码)是:

int main(int argc, char *argv[]) {
    MPI_Init(&argc, &argv);  
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);

    if (myid == 0) { // Do the serial part on a single MPI thread
        printf("Performing serial computation on cpu %d\n", myid);
        PreParallelWork();
    }

    ParallelWork();  // Every MPI thread will run the parallel work

    if (myid == 0) { // Do the final serial part on a single MPI thread
        printf("Performing the final serial computation on cpu %d\n", myid);
        PostParallelWork();
    }

    MPI_Finalize();  
    return 0;  
}  

关于c - 如何通过MPI加速这个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2156714/

相关文章:

time - 在科学集群上使用并行处理时 $time 意味着什么?

c++ - MPI_Allreduce 加倍

c++ - MPI_ERR_TRUNCATE : On Broadcast

gcc - 如何使用 Homebrew 软件和 gcc-4.9 构建 openmpi?

c - 不使用 printf 打印新行

c++ - 如何创建彩条(电视测试图案)

c - 如何将参数传递给 C 语言中的 main() 函数?

c - 内存:在图表的顶部或底部的高地址?

c++ - MPI 查找位移的不同方法

c - 从 OpenMP 到 MPI