Linux mpi 程序示例

来源:互联网 发布:qq空间淘宝应用可信吗 编辑:程序博客网 时间:2024/05/22 23:54
基于MPICH的并行程序设计
  
  
  下面用一个简单的例子,给出在Linux平台上开发MPI并行程序的一个基本框架,以便对基于MPICH的并行程序有一个感性认识。基于MPICH的并行程序可以用C或者Fortran开发,此处给出的例子是用C语言编写的。
  
  /*====================*
  * mpi_hello.c - Demo program of MPICH. *
  *====================*/
  
  #include
  #include “mpi.h”
  
  int main(int argc, char **argv)
  {
  int myrank, nprocs, namelen;
  char processor_name[MPI_MAX
  _PROCESSOR_NAME];
  
  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_
  WORLD, &nprocs);
  MPI_Comm_rank(MPI_COMM
  _WORLD, &myrank);
  MPI_Get_processor_name(processor_name, &namelen);
  
  printf(“Hello World! I’m rank %d of %d on %s\n”, myrank,
  nprocs, processor_name);
  
  MPI_Finalize();
  return 0;
  }
  
  
  
  为了保证编译的正确性,程序的首部必须包含MPI的头文件mpi.h。该文件给出了MPI所有调用接口的说明,并对所有用到的常量进行了定义。MPI_MAX_PROCESSOR_NAME就是该文件中定义的一个常量,是某一MPI具体实现(此处即为MPICH)中允许的主机名的最大长度。
  
  在调用任何MPI函数之前,必须先调用MPI_Init()进行相应的初始化工作。当所有MPI函数调用都完成之后,还必须调用MPI_Finalize()进行相应的清理工作。命令行参数通过MPI_Init()函数传递给MPI,以便为各个并行执行的程序建立起正确的运行环境。
  
  接下去的几个MPI函数用来获得并行计算环境的一些基本信息。上面的示例程序只是简单地输出了这些信息,但通常情况下这些信息将被用来进行问题的自动分解,或者用于建立各并行机间的通信。MPI_Comm_size()函数可以得到参与并行计算的进程个数;MPI_Comm_rank()函数可以得到当前正在运行的进程的标识;而MPI_Get_processor_name()函数则能够获得当前进程所在主机的名称。
  
  基于MPI的并行程序可能有很多种编译方法,大多数MPI实现都提供了一个易于使用的脚本来完成编译,这些脚本能够为编译器设置合适的参数,帮助编译器找到MPI头文件所在的目录,并能够连接上所需的库文件,从而保证编译过程的正确性。MPICH和LAM都提供了一个名为mpicc的脚本来完成并行程序的编译。例如,要编译上述的示例程序,只需执行下面的命令即可:
  
  $ mpicc -o mpi_hello mpi_hello.c
  
  
  
  在并行环境中的多台计算机上同时执行该程序,要将编译好的程序复制到不同的机器上,并且可执行程序必须放 $ mpirun -np 6 mpi_hello
  
  
  
  在MPICH中,mpirun是MPI程序的启动脚本,它简化了并行进程的启动过程,尽可能屏蔽了底层的实现细节,从而为用户提供了一个通用的MPI并行机。在用mpirun命令执行并行程序时,参数-np指明了需要并行运行的进程个数。mpirun首先在本地结点上启动一个进程,然后根据/usr/local/share/machines.LINUX文件中所列出的主机,为每个主机启动一个进程。若进程数比可用的并行节点数多,则多余的进程将重新按照上述规则进行 Hello World! I′m rank 0 of 6 on node1
  Hello World! I′m rank 1 of 6 on node2
  Hello World! I′m rank 5 of 6 on node3
  Hello World! I′m rank 3 of 6 on node1
  Hello World! I′m rank 2 of 6 on node2
  Hello World! I′m rank 4 of 6 on node3
  
  
  
  
  基于PVM的并行程序设计
  
  
  在用PVM进行并行程序设计时,程序员首先要将被求解的问题分解成独立的程序,然后用C或者Fortran实现每个程序,最后再通过PVM提供的虚拟机在整个并行计算环境中运行。下面用一个简单的例子,给出在Linux平台上开发PVM并行程序的一个基本框架。
  
  /*===================*
  * pvm_hello.c - Demo
  program of PVM.*
  *==================*/
  
  #include
  #include “pvm3.h”
  
  int main(int argc, char** argv)
  {
  int i, mytid, dtid, info, nhost, narch;
  struct pvmhostinfo* hostp;
  
  mytid = pvm_mytid();
  dtid = pvm_tidtohost(mytid);
  info = pvm_config(&nhost, &narch, &hostp);
  
  for (i = 0; i < nhost && hostp[i].hi_tid != dtid; i++)
  ;
  printf(“Hello World! My task id is t%x on %s with %d hosts.\n”,
  mytid, hostp[i].hi_name, nhost);
  
  pvm_exit();
  return 0;
  }
  
  
  
  上述示例程序给出了启动和终止一个PVM程序的基本步骤:首先在程序首部包含PVM的头文件pvm.h。然后调用pvm_mytid()函数获得当前运行进程的任务标识符,调用pvm_tidtohost()函数获得与任务标识符对应的主机标识符。若想获得当前进程所在虚拟机的相关信息(如主机总数和平台种类等),则可以通过调用函数pvm_config()来实现。最后,当所有的PVM函数都执行完后,调用pvm_exit()函数来结束整个并行计算过程。
  
  PVM没有提供一个单独的脚本来完成编译过程,要编译上述示例程序,需要手工执行以下命令:
  
  $ gcc -o pvm_hello -I/usr/local/src/pvm3/include/ \
  > -L/usr/local/src/pvm3/lib/LINUX/ pvm_hello.c -lpvm3
  
  
  
  同MPICH一样,用PVM编写的程序要想能够在多台主机上并行运行,首先要将编译好的可执行文件复制到不同的机器上。PVM要求用户运行的可执行文件都应该位于Home目录下的pvm3/bin/LINUX下。例如,要想在node1上以gary账户启动上述示例程序,同时要求node2和node3能够并行执行该程序,则应先将可执行文件pvm_hello复制到node1、node2和node3机器上的/home/gary/pvm3/bin/LINUX目录下,然后在node1上执行如下命令:
  
  $ cd ~/pvm3/bin/LINUX
  $ pvm
  pvm> add node2 node3
  pvm> spawn -6 -> pvm_hello
  pvm> halt
  
  
  
  PVM专门提供了一个Shell来对并行执行的任务进行管理和调度。上述程序中add命令用来添加一个新的并行节点机;spawn命令用来启动一个并行程序,参数“-6”指明了并行执行的进程个数,参数“->”指示将输出信息显示在屏幕上;halt命令则用来终止整个并行计算虚拟机。
  
  上述示例程序的一次执行结果如下所示:
  
  [1:t40002] Hello World! My task id is t40002 on node1 with 3 hosts.
  [1:t40002] EOF
  [1:t40003] Hello World! My task id is t40003 on node1 with 3 hosts.
  [1:t40003] EOF
  [1:tc0002] Hello World! My task id is tc0002 on node3 with 3 hosts.
  [1:t80001] Hello World! My task id is t80001 on node2 with 3 hosts.
  [1:t80001] EOF
  [1:tc0001] Hello World! My task id is tc0001 on node3 with 3 hosts.
  [1:tc0001] EOF
  [1:tc0002] EOF
  [1:t80002] Hello World! My task id is t80002 on node2 with 3 hosts.
  [1:t80002] EOF
  [1] finished
  
  
  
  并行计算使用多台计算机或者具有多个处理器的计算机来求解问题,从而为求解大规模复杂问题提供了可能。作为一个优秀的操作系统,Linux特别适合用来组建并行计算平台。