Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2338726
  • 博文数量: 609
  • 博客积分: 10061
  • 博客等级: 上将
  • 技术积分: 5920
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-25 08:30
文章分类

全部博文(609)

文章存档

2010年(13)

2009年(39)

2008年(558)

我的朋友

分类:

2008-08-29 09:26:10

PVM程序设计基础

  • PVM介绍

    PVM是用于在UNIX计算机间传送系统的系统,使用PVM可以将许多台计算机连结成一台大型分布式存储并行计算机。这个网络我们称之为虚拟机。我们可以 在不同的层次上使用PVM。在最高层次上,也就是透明模式下,任务被自动分配到最合适的计算机上执行;在下一个层次上,也就是体系结构相关模式下,用户可 以指定运行此任务的计算机类型;在最低的层次上,用户可以指定一台特定的机器来执行特定的任务。无论采用哪种模式,PVM都负责管理计算机间数据的传送和 低层数据传送的相关问题。PVM是一种十分灵活的消息传递系统,它支持最一般的MIMD并行计算结构,这就使得几乎任何结构都可以在PVM上建立。


  • 编程初步

    如果您使用C语言编写PVM程序,下面将是所有程序所必须拥有的结构。每个PVM程序应该包含PVM头文件,此文件包含了PVM编程接口信息,通过下面的语句可以实现包含头文件的工作:
    将“#include "pvm3.h"”或“#include "fpvm3.h"”放在C程序的开始处。 在编写MAIN函数时,第一句通常是调用一个PVM函数:info=pvm_mytid(),它的作用是将当前进程在PVM内注册,获得一个进程号,如果返回一个负数,那就是出错了。 当PVM程序结束时,都应该有下面的语句:pvm_exit();

    并行程序起码要有多个任务,如何生成多个任务呢?生成多个任务是通过调用下面函数完成的:pvm_spawn(),以后我们还会仔细讲解此函数的用法,现在我们只简单介绍一个例子:
    num=pvm_spawn("task", NULL, PvmTaskDefault, 0, ntask, tids_string);

    这条语句将程序task生成ntask个复本并运行在由PVM选定的计算机上。程序的返回值num说明实际产生了几个任务。 生成了许多任务,可是它们的名字是什么呢?tids_string是一个数组,生成任务的任务号就存储在这个数组中。每个PVM进程都它唯一的进程号,也就是任务号。

    在最后,我想开始学习一门新语言的最佳办法还是看一些标准的例子,这些例子都可以从网上直接获得。

  • 编译和运行
    为了运行程序必须编译它,您可以在计算机上使用下面命令对tt.c进行编译:
    cc -L~/pvm3/lib/(计算机结构名) tt.c -lpvm3 -o foo
    在编译结束后还要把可执行文件放在下面的目录中:~/pvm3/bin/ARCH,同样,需要在别的机器上运行的程序也要按照它的结构进行编译。在运行了PVM之后,通过在命令行下输出文件名运行此文件。

  • 任务间通信
    在学会了上面的内容之后就要学习如何进行真正的并行程序设计了。并行程序的不同任务之间必须进行通信以便达到同步和共享数据等等目的。从A进程向B进程发 送消息之前,必须调用pvm_initsend()函数,它的作用是清空默认的缓冲区,指定传送数据所用的编码,下面是一个例 子:bufid=pvm_initsend(PvmDataDefault)。在初始化后,发送进程必须将数据打包,这由一组pvm_pack()函数完 成,具体内容请看编程手册。

    完成将数据打包放入缓冲区后,可以调用pvm_send()函数完成发送,下面是它的例子:info=pvm_send(tid, msgtag)。其中tid指接收进程的进程号,msgtag指明数据的类型;当需要向许多进程发送消息(或数据)时,pvm_mcast()函数是最合适的。

    接收进程调用pvm_recv()函数接收发送过来的数据,注意它的用法:bufid=pvm_recv(tid, msgtag),其中tid指发送进程的进程号,而msgtag指的是数据类型,接收进程将等待tid进程发来的数据类型为msgtag的数据,当然用户也可以将这两个值取为-1,它的意思是此进程可以接收进程发送过来的任何类型的数据。PVM 3.3加入了pvm_trecv()函数以控制接收时间不允许超时。使用pvm_probe()函数可以检查是否有数据发送过来。

    进程接收数据后,必须对数据解包,解包由pvm_unpack()实现,在解包的时候请注意顺序问题,如果顺序错误,可能带来意想不到的错误。在使用PVM 3.3时,用户可以使用pvm_psend()函数一次完成打包和发送工作,这就方便得多了。


  • 动态进程分组
    动态进程分组在一些进程执行相同或类似功能时可能会用到,用户可以给这些进程一个名字,这些进程除了进程号外还有了一个组号以示区别。可以通过执行 num=pvm_joingroup("组名")将某个进程加入到某个组中,如果这个组不存在,就新建一个组,num是这个函数的返回值,它指示了组号, 一个进程可以同时属于不同的组,想从某个组中离开时,可以调用下面的函数pvm_lvgroup(),注意,在离开时要进行一些处理否则会留下空隙。

    通过下面几个函数可以取得有关组的信息:pvm_getinst()返回一个进程的组例;pvm_gettid()返回组号;pvm_gsize():返 回组大小。可以通过下面的函数向组向的进程发送数据:pvm_bcast()。pvm_barrier()函数用于进程的同步,任何一个调用 pvm_barrier()的进程将停止执行,直到组内其它进程也调用此函数为止。

  • 负载平衡
    对于应用程序来说负载平衡是很重要的,一定要保证每台机器都有活干,不要一台机器累死,其它机器闲死,保证负载平衡才能保证效率。保持负载平衡的最简单的 方法是静态负载平衡,使用这种方法时,任务在进行前就已经分配好,运行中不进行改变,每个机器根据自己运算能力的大小可能被分配不同数量的进程,对于轻载 程序来说,这是很好的办法。

    当运算负载差别比较大,动态负载平衡就比较好了。最好的方法称之为:任务池方法,它通常用主从式结构实现,主进程管理从进程,当从进程空闲时,主进程就给 它分配一个任务。如果进程和进程之间需要通信,这种方法就不好用了,就需要采用第三种平衡方法进行负载平衡,在这种方法下,进程在运行一段时间后停止,然 后通过对进程运行情况的检查确定负载平衡的方法,不同的应用程序可能需要不同的方法才能达到最佳的效果。


  • 达到高效率
    PVM不限制用户编制程序的方法,但有些建议希望用户能够采纳。首先是任务的粒度,它指的是任务的通信量和运算量之间的比值,加大任务的粒度会命名程序速 度变快一些,但并行性却下降了。下一个是参与通信的包的数量,一般来说,需要包的数目越多所用的时间就越多。尽量做到通信和计算并行,这样是最合适的。一 些程序适合于功能并行,一些适合于数据并行,在功能并行中,不同的机器会根据自己的计算能力选择不同的任务运行,例如:大型机会选择完成问题中的向量计算 部分,而多处理机选择完成问题中的并行成分,而图形工作站选择完成问题所要求的实时图象显示,各取所长。在数据并行中,数据在虚拟机中传送,根据得到的数 据不同的进程完成相应的功能,然后进程将完成的结果回送,当然PVM允许用户同时两种模型进行编程。如果用户使用多台计算机,网络传输的问题也应该考虑在 内,尽管所有的机器都是一样的,但可能因为不同机器上有不同的用户数,处理能力相差也很远,这时就需要另外采取措施进行改进。
阅读(1564) | 评论(0) | 转发(0) |
0

上一篇:XenNetworking

下一篇:CentOS Cluster群集套件

给主人留下些什么吧!~~