C指针原理(32)--C语言-pvm并行计算

时间:2019-04-18
本文章向大家介绍C指针原理(32)--C语言-pvm并行计算,主要包括C指针原理(32)--C语言-pvm并行计算使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1、配置PVM

并行计算机(pvm)是用于网络并行计算机上的软件工具。设计它的目的是将异构的计算机网络连接起来,使它使用起来就像一组分布式的并行处理器。

PVM支持多种并行计算模型,用户使用PVM提供的函数库可进行并行程序或分布式程序的设计工作,使用传统的C语言和Fortran语言。系统提供了一组便于使用的通信原语,可实现一个任务向其它任务发消息,向多个任务发消息,以及阻塞和无阻塞收发消息等功能,用户编程与网络接口分离。

1)环境

PVM_ROOT=/usr/lib/pvm3为配置根目录

PVM_ARCH=LINUX为配置计算机类型,包括unix

deepfuture-lx@deepfuture-lx-desktop:/usr/lib/jvm$ sudo gedit /etc/environment

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/jvm/java-6-sun/bin"

CLASSPATH=.:/usr/lib/jvm/java-6-sun/lib

JAVA_HOME=/usr/lib/jvm/java-6-sun

PVM_ROOT=/usr/lib/pvm3

PVM_ARCH=LINUX

  1. PVM环境中的二进制程序的目录和需要使用的用户名

二进制程序目录名默认为PVMROOT/bin/PVM_ROOT/bin/PVM_ARCH

ep为二进制程序目录名,lo为使用非登录PVM环境用户的用户名,deepfuture-laptop为主机名,&主机名表示PVM环境不自动增加这些主机

例如:

deepfuture@deepfuture-laptop:/usr/lib/pvm3$ sudo gedit hostfile

deepfuture-laptop

&deepfuture-javaeye

&deepfuture-lx lo=deepfuture

ep=/home/deepfuture/private/mytest/pvmtest/

  1. 列出希望使用的所有主机

.rhosts文件

deepfuture-laptop

4)启动pvmd程序

deepfuture@deepfuture-laptop:/usr/lib/pvm3$ pvmd hostfile &或者

deepfuture@deepfuture-laptop:/usr/lib/pvm3$ pvmd &

5)通常程序(二进制文件)的缺省目录为:

$HOME/pvm3/bin/

6)启动

deepfuture@deepfuture-laptop:/usr/lib/pvm3$ pvm

pvmd already running.

pvm> quit

quit

如果启动失败,则清除临时文件

deepfuture@deepfuture-laptop:/usr/lib/pvm3$ sudo rm -f /tmp/pvm.

7)运行程序,testpro为程序名

$testpro

pvm>spawn -> testpro

安装完PVM以后,还需要编辑/ect/hosts文件,来列出你要加入的所有主机名及其对应的IP地址,以便在用add命令来加入主机时,PVM可以根据主机名来寻找相应的IP,从而确定相应的主机。基本格式如下:

      hostname1 10.30.13.58(numeric IP) 

      hostname2 10.30.13.62 

      …    ….      …. 

每行一个主机。

将激活的消息缓冲区的内容放入一个预定类型的数组中

NAME

pvm_unpack - Unpack the active message buffer into arrays of prescribed data type.

SYNOPSIS

· Cint info = pvm_unpackf( const char *fmt, … )

· int info = pvm_upkbyte( char *xp, int nitem, int stride)

· int info = pvm_upkcplx( float *cp, int nitem, int stride)

· int info = pvm_upkdcplx( double *zp, int nitem, int stride)

· int info = pvm_upkdouble( double *dp, int nitem, int stride)

· int info = pvm_upkfloat( float *fp, int nitem, int stride)

· int info = pvm_upkint( int *ip, int nitem, int stride)

· int info = pvm_upkuint( unsigned int *ip, int nitem, int stride )

· int info = pvm_upkushort( unsigned short *ip, int nitem, int stride )

· int info = pvm_upkulong( unsigned long *ip, int nitem, int stride )

· int info = pvm_upklong( long *ip, int nitem, int stride)

· int info = pvm_upkshort( short *jp, int nitem, int stride)

· int info = pvm_upkstr( char *sp )

· PVM是一个在网络上的虚拟并行机系统的软件包。它允许将网络上基于UNIX操作系统的并行机和单处理机的集合当成一台单一的“并行虚拟机”来使用。 2.1 PVM的产生和发展 PVM的开发最早开始于1989年夏天,目前它的开发队伍包括美国橡树岭国家实验室(ORNL)、Tennessee大学、Emory大学以及CMU等单 位,并得到美国能源部、国家科学基金以及田纳西州的资助。PVM是一套并行计算工具软件,支持多种体系结构的计算机,象工作站、并行机以及向量机等,通过 网络将它们连起来,给用户提供一个功能强大的分布存储计算机系统。PVM支持C和Fortran两种语言,目前已发展到3.4版,由于它是免费的,因此使 用范围非常广泛。 2.2 PVM的特点 PVM支持用户采用消息传递方式编写并行程序,计算以任务(task)为单位,一个任务就是一个UNIX进程,每个任务都有一个taskid来标识(不同 于进程号)。PVM支持在虚拟机中自动加载任务运行,任务间可以相互通讯以及同步。在PVM系统中,一个任务被加载到哪个结点上去运行,一般来说,对用户 是透明的(PVM允许用户指定任务被加载的结点),这样就方便了用户编写并行程序。 归结起来,PVM的特点有如下几点: PVM系统支持多用户及多任务运行,多个用户可将系统配置成相互重叠的虚拟机,每个用户可同时执行多个应用程序。 易于编程。PVM支持多种并行计算模型,用户使用PVM提供的函数库可进行并行程序或分布式程序的设计工作,使用传统的C语言和Fortran语言。 系统提供了一组便于使用的通信原语,可实现一个任务向其它任务发消息,向多个任务发消息,以及阻塞和无阻塞收发消息等功能,用户编程与网络接口分离。系统 还实现了通信缓冲区的动态管理机制,每个消息所需的缓冲区由PVM运行时动态申请,消息长度只受结点上可用存储空间的限制。 PVM提出了进程组的概念,可以把一些进程组成一个进程组,一个进程可属于多个进程组,而且可以在执行时动态改变。 支持异构计算机联网构成并行虚拟计算机系统且易于安装、配置。PVM支持的异构性分为三层:机器层、应用层和网络层。也就是说,PVM允许应用任务充分利 用网络中适于求解问题的硬件结构;PVM处理所有需要的数据转换任务;PVM允许虚拟机内的多个机器用不同的网络(FDDI,Token RING和Ethernet等)相连。 具有容错功能,当发现一个结点出故障时,PVM会自动将之从虚拟机中删除。 结构紧凑。整个系统只占3M左右的空间,并且该软件系统是免费提供的

示例:

1、主进程 testpvm1,发送字符串,接收大写化的字符串

C代码 收藏代码

#include "pvm3.h"  

#include <stdio.h>  

  

  

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

   int RetCode,MessageId;  

   int PTid,Tid;  

   char Message[100];  

   char Result[100];  

   printf("testpvm1 get ptid.....\n");     

  

   PTid=pvm_mytid();//返回调用进程的任务标识符  

   if (PTid==PvmSysErr) perror("pvm_mytid() error:PvmSysErr\n");  

   printf("spawn testpvm2.....\n");     


   RetCode=pvm_spawn("testpvm2",NULL,PvmTaskHost,"deepfuture-laptop",1,&Tid);  

//启动一个新的PVM子进程testpvm2,用来接收和处理Message消息,转化为大写,Tid为新的任务标识  

   if (RetCode==1){  

       MessageId=1;//指明当前消息  

   strcpy(Message,"deepfuture.iteye.com");  

   pvm_initsend(PvmDataDefault);//初始化消息缓冲区  

   pvm_pkstr(Message);//对变量Message的内容进行打包      

   pvm_send(Tid,MessageId);//将消息缓冲区的消息发送,MessageId简单指明正在发送的消息  

   pvm_recv(Tid,MessageId);//接收消息  

   pvm_upkstr(Result);//将消息缓冲区的接收到的内容放到一个数组中。  

   printf("send:%s\n",Message);  

   printf("recv:%s\n",Result);  

   pvm_exit();  

   return 0;        

}

else{

   printf("不能启动新进程\n");  

   pvm_exit();         

   return 1;  

}

}

2、从进程 testpvm2,将字符串转化为大写,然后返回给主进程

C代码 收藏代码

#include "pvm3.h"  

#include <stdio.h>  

  

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

   int RetCode,MessageId;  

   int PTid;  

   char Message[100];  

   char myc[100];  

   int i=0;  

  

   printf("testpvm2 get ptid.....\n");   

   

   PTid=pvm_parent();//返回调用进程的任务标识符  

   if (PTid==PvmNoParent) perror("PvmNoParent error\n");  

   else if (PTid==PvmSysErr) perror("PvmSysErr error\n");  

     

   printf("testpvm2 run.....\n");     

  

   MessageId=1;//指明当前消息  

   pvm_recv(PTid,MessageId);//接收消息   



   pvm_upkstr(Message);//对变量Message的内容进行解包   

   while (Message[i]!='\0'){ //将小写转化成大写  

              if (islower(Message[i]))     

                  myc[i]=toupper(Message[i]);   

              else   

                  myc[i]=Message[i];      

       i++;   

   }   

   myc[i]='\0';    

   pvm_initsend(PvmDataDefault);//初始化消息缓冲区   

   pvm_pkstr(myc);//对变量Message的内容进行打包  

   pvm_send(PTid,MessageId);//将消息缓冲区的消息发送,MessageId简单指明正在发送的消息  

   pvm_exit();  

   return 0;       

  

}  

3、makefile

Makefile代码 收藏代码

testpvm:testpvm1 testpvm2

sudo cp /home/deepfuture/private/mytest/pvmtest/testpvm1 /usr/lib/pvm3/bin/LINUX/testpvm1  

sudo cp /home/deepfuture/private/mytest/pvmtest/testpvm2 /usr/lib/pvm3/bin/LINUX/testpvm2   

testpvm1:

gcc -o /home/deepfuture/private/mytest/pvmtest/testpvm1 -lpvm3 /home/deepfuture/private/mytest/testpvm1.c  

testpvm2:

gcc -o /home/deepfuture/private/mytest/pvmtest/testpvm2 -lpvm3 /home/deepfuture/private/mytest/testpvm2.c  

clean:

rm /home/deepfuture/private/mytest/pvmtest/testpvm*  

sudo rm /usr/lib/pvm3/bin/LINUX/testpvm*  

4、二进制文件存放目录 为

   $PVM_ROOT/bin/$PVM_ARCH

   本机为/usr/lib/pvm3/bin/LINUX/

5、启动pvmd

pvmd &

6、运行testpvm1

xxxxxxx@xxxxxx-laptop:/usr/lib/pvm3/bin/LINUX$ ./testpvm1

7、在pvm控制台运行testvpm1

deepfuture@deepfuture-laptop:/usr/lib/pvm3/bin/LINUX$ pvm

pvmd already running.

pvm> spawn -> testpvm1

spawn -> testpvm1

[1]

1 successful

t40042

pvm> [1:t40043] testpvm2 get ptid…

[1:t40043] testpvm2 run…

[1:t40042] testpvm1 get ptid…

[1:t40042] spawn testpvm2…

[1:t40042] send:deepfuture.iteye.com

[1:t40042] recv:DEEPFUTURE.iteye.com

[1:t40042] EOF

[1:t40043] EOF

[1] finished

8、ubuntu使用新立得安装pvm3、libpvm3、pvm-dev

PVM安装调试及应用程序编译链接测试

说明:

1.以两台机器为例,假定所用机器名为pvm01(202.113.12.151)和pvm02(202.113.12.152)。要求网络工作正常。

2.运行并行程序需要在各个结点机上有相同的用户名和密码,并有相应的配置。这里我们假定用户名为pvmgroup,密码pvmgroup。

3.例子程序为Master-Slave并行程序,用来计算Pi值,同时做一些相应的统计。dtiming为Master程 序,dtiming_slave为slave程序,Makefile.aimk是PVM程序编译与链接程序aimk所使用的文件,功能与Makefile 文件相同。

一、运行环境配置与调试

1.修改/etc/hosts文件。

添加

202.113.12.151 pvm01

202.113.12.152 pvm02

2.如果是csh,修改(创建)/home/pvmgroup/.cshrc文件

setenv PVM_ROOT /usr/share/pvm3

setenv PVM_ARCH LINUX

setenv PATH /usr/share/pvm3/lib:./$PATH

如果是bash,则修改.bash_profile

Get the aliases and functions

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi

User specific environment and startup programs

PATH=PATH:PATH:HOME/bin:/usr/share/pvm3/lib

BASH_ENV=$HOME/.bashrc

USERNAME=""

PVM_ROOT=/usr/share/pvm3

PVM_ARCH=LINUX

export USERNAME BASH_ENV PATH PVM_ROOT PVM_ARCH

3.修改(创建)/home/pvmgroup/.rhosts文件。

pvm01 pvmgroup

pvm02 pvmgroup

4.调试

$ pvm

pvm> add pvm01

add pvm01

1 successful

                HOST     DTID

               pvm01    80000

pvm> halt

halt

Terminated

如果各个结点都正确配置屏幕将有如上输出,其中斜体为用户输入。如果配置有误,将报相应错。

二、PVM应用程序的编译、链接与运行

1.创建目录/home/pvmgroup/pvm3/bin/LINUX。(编译好的程序要放到这里)

2.COPY源程序及Makefile.aimk到/home/pvmgroup/pvm3/bin/LINUX目录下。

3.$ cd /home/pvmgroup/pvm3/bin/LINUX

$ ./aimk

4.将生成的可执行文件FTP到各结点机的相同目录下,并增加可执行属性。

或者在每个结点机上都编译、链接一遍。

如果是异构结点机,必须重新编译。

5.启动PVM,运行程序,步骤及正常运行结果如下:

$ pvm

pvm> add pvm01

add pvm01

1 successful

                HOST     DTID

               pvm01    80000

pvm> quit

quit

Console: exit handler called

pvmd still running.

$ ./dtiming

i’m t40002

there has 2 machines!

slave 0 is task t80001 ok,send parameter to task 0

slave 1 is task t40003 ok,send parameter to task 1

The start time is:1026871885

task 0 finished! return is 0.8472130900904784

the time is:11

task 1 finished! return is 0.9270373444467532

the time is:0

the total time is:11

result is 3.1415926928720199

$

其中斜体为用户输入,其余为系统输出。机器不同,输出的结果也会有所不同。