|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
java也能做一些底层语言开发做的事情(难度很高,不是java顶尖高手是做不来的),构建本人的基于Java的超等盘算机转载自:假如您曾想过构建本人的超等盘算机,但却对用C言语举行并行编程望而却步,那末伪远程线程能够帮您办理这一成绩。这类获奖的Java编程模子极年夜地简化了集群上的并行编程,并使超等盘算走出实行室,使每位Java程序员都能利用它。
在已往的三年里,并行集群已在改动着超等盘算的相貌。一旦代价数百万美圆的单体机占了主导,并行集群很快就会成为超等盘算机的选择。能够想像失掉,开放源码圈内的低落热忱已招致发生了数百--假如不是数千的话--并行集群项目。第一个同时也是最出名的开放源码集群体系是Beowulf。在NASA援助下,由ThomasSterling和DonaldBecker在1994年公布的Beowulf,入手下手是作为一个16节点演示集群推出的。明天,Beowulf已无数百种完成,从OakRidge国度实行室的StoneSouperComputer到Aspen体系公司的定制构建的贸易性集群(请参阅参考资本)。
对Java程序员倒霉的是,多半集群体系都是环绕基于C言语的软件动静传送API―如动静传送接口(MPI)或并行假造机(PVM)―来完成的。用C言语举行并行编程不是件简单的事,因而我计划了一个替换计划。本文将申明怎样综合使用Java线程和Java远程办法挪用(RMI)来创立本人的基于Java的超等盘算机。
请注重,本文假定您有Java线程和RMI的使用常识。
超等盘算机内有甚么?
超等盘算机的界说是:由八个或更多的节点构成、作为单个高功能呆板事情的集群。基于Java的超等盘算机包括一个功课调剂器和恣意数目的运转服务器(也称为主机)。功课调剂器天生多个线程,每一个线程包括实行分歧子义务的代码。各个线程将其代码迁徙到分歧的运转服务器上。然后,每一个运转服务器实行迁徙给它的代码并将了局前往给功课调剂器。最初,功课调剂器将各个线程的了局组合起来。
这类并行集群体系之以是被称为伪远程线程,是由于线程是在功课调剂器上调剂的,但线程内的代码倒是在远程盘算机上实行的。
该体系有哪些组件?
组件一词是指构成“伪远程线程”并行集群体系的逻辑模块。该体系包括以下组件:
Jobdispatcher(功课调剂器)是实行把持的呆板。它天生分歧的线程,每一个线程都包括此集群要处置的主义务的一个子义务。每一个线程内的代码都被发送到一台远程盘算机往实行。线程在功课调剂器上调剂,以是实际上讲,该呆板不该该用于实行任何子义务。
SubTask是一个用户界说类,该类界说主义务的一个数据或功效自力的部分。您能够为主义务的分歧部分界说分歧的类。类名SubTask是一个示例。您能够为一个SubTask类取任何名字,不外这个名字应当能形貌分派给它的子义务。在界说SubTask类时,您必需完成JobCodeInt接口和jobCode()办法,上面对其举行申明。
JobCodeInt是一个Java接口。您必需在界说子义务的类中完成该接口和jobCode()办法。jobCode()办法形貌了将在远程实行的代码。假如您盘算在远程利用某个当地资本,您必需在jobCode()办法内部初始化这个资本。例如说,您要将一组图象发送到远程处置,就必需在jobCode()办法内部初始化Image对象。您能够在该办法中挪用尺度Java库中的类,由于远程盘算机上存在这些库。
RunServer是一个Java对象,该对象同意远程历程挪用其办法。它的一个办法以完成了JobCodeInt接口的对象作为参数。RunServer就在运转该对象的盘算机(运转服务器)上实行该对象内的代码,并将盘算了局作为Object类的一个实例前往。Object是Java类条理布局中最高一级的类。
PseudoRemThr是一个Java类,该类封装了一个线程并承受给定SubTask类的一个实例。它选择一台远程主机,并将SubTask实例发送到这台主机上实行。假如您要使用某台主机上可用的特定资本(诸如数据库或是打印机),则能够指定主机。
HostSelector是一个模块。假如您没有指定远程主机,PseudoRemThr类就会挪用HostSelector模块来选择特定的主机。假如没有余暇的主机,HostSelector会前往负载最小的远程盘算机。假如某个远程盘算机是一个多处置器体系,HostSelector大概会不止一次地前往该主机名。今朝,HostSelector没法依据给定义务的庞大水平来选择主机。
伪远程线程的事情体例
要利用伪远程线程,您必需完成功课调剂器和运转服务器。本节将申明怎样完成各个部分。
完成功课调剂器
起首,将主义务分化为数据或功效自力的子义务。针对每一个子义务,界说一个完成JobCodeInt接口(从而完成jobCode()办法)的类。在jobCode()办法中,界说各给定子义务要实行的代码。
请注重,您不克不及挪用功课调剂器上用户界说的的当地资本。请在该办法内部初始化一切这类资本。比方,您能够在SubTask类的机关函数中初始化这类资本。
创立类PseudoRemThr的多少实例,并将SubTask的实例传送给PseudoRemThr的各个实例。假如您要明白指定一台远程主机,您能够经由过程挪用PseudoRemThr对象的另外一个机关函数来完成。
守候这些线程完成。挪用getResult()办法来猎取PseudoRemThr的各个实例的实行了局。假如盘算没有完成,了局前往一个值为false的Boolean对象;不然,将前往Object类的一个实例,个中包括了盘算了局。您必需将此实例转换为您所但愿的类范例。将一切的子义务了局组合为终极了局。
完成运转服务器
完成运转服务器是一项复杂的事情:
启动RMI注册程序。
启动RunServer。
运转服务器在启动时接通功课调剂器,并关照功课调剂器它已筹办停当,能够承受要实行的义务了。
一个盘算示例
如今该测试这一模子了。以下盘算示例利用两台盘算机并交运行。一台是运转Windows98的333MHzPentiumII盘算机,另外一台是运转Windows2000专业版的500MHzPentiumIII盘算机。
为了盘算从1到10^9的一切整数的平方根之和,我创立了Sqrt类,它盘算dblStart和dblEnd之间一切整数的平方根之和。
Sqrt完成JobCodeInt接口,因而也完成了jobCode()办法。在jobCode()办法中,我界说了完成这一盘算的代码。
机关函数用于将数据传送给Sqrt类,并初始化功课调剂器上的一切当地资本。必需将要盘算其平方根之和的整数的起止点发送给机关函数。清单1是Sqrt类的界说
清单1.界说Sqrt类
//Sqrt类盘算dblStart和dblEnd之间的一切整数的平方根之和。
//盘算在jobCode()办法内完成
//该类完成JobCodeInt接口,且完成代码位于jobCode()办法内
//在机关函数中将数据传送给该类,并初始化功课调剂器上的当地资本。
//本例中,要盘算其平方根之和的整数序列的起止点被发送给Sqrt类
publicclassSqrtimplementsJobCodeInt
{
doubledblStart,dblEnd,dblPartialSum;
publicSqrt(doubleStart,doubleEnd)
{
dblStart=Start;
dblEnd=End;
}
publicObjectjobCode()
{
dblPartialSum=0;
for(doublei=dblStart;i<=dblEnd;i++)
//可挪用尺度的Java函数和对象。
dblPartialSum+=Math.sqrt(i);
//前往了局,一个尺度Java类的对象。
return(newDouble(dblPartialSum));
}
}
JobDispatcher类创立Sqrt类的两个实例。然后分化主义务,将一项子义务分派给一个Sqrt对象(Sqrt1),并将余下的子义务分派给另外一个Sqrt对象(Sqrt2)。接上去,JobDispatcher创立PseudoRemThr类的两个对象,并将Sqrt对象作为参数分离传送给它们。接上去就守候线程实行。
一旦线程实行终了,便可从每一个PseudoRemThr实例取得部分了局。将各部分了局组合起来便可失掉终极了局,如清单2所示。
清单2.事情中的JobDispatcher
//此类能够定名为您选择的任何称号
//这里选用JobDispatcher只是为了便利
publicclassJobDispatcher
{
publicstaticvoidmain(Stringargs[])
{
doublefin=10000000;//代表10^9
doublefinByTen=fin/10;//代表10^8
longnlStartTime=System.currentTimeMillis();
//局限从1到3*10^8
Sqrtsqrt1=newSqrt(1,finByTen*3);
//局限从((3*10^8)+1)到10^9
Sqrtsqrt2=newSqrt((finByTen*3)+1,fin);
//以下创立PseudoRemThr类的两个实例。//此机关函数的参数以下所示。//第一个参数:代表子义务的某个类的实例
//第二个参数:实行这一子义务的远程主机
//第三个参数:PseudoRemThr实例的形貌性称号。
PseudoRemThrpsr1=new
PseudoRemThr(sqrt1,"//192.168.1.1:3333/","Win98");
PseudoRemThrpsr2=new
PseudoRemThr(sqrt2,"//192.168.1.2:3333/","Win2K");
psr1.waitForResult();//守候实行停止//猎取每一个线程的了局
Doubleres1=(Double)psr1.getResult();
Doubleres2=(Double)psr2.getResult();
doublefinalRes=res1.doublevalue()+res2.doublevalue();
longnlEndTime=System.currentTimeMillis();
System.out.println("Totaltimetaken:"+(nlEndTime-nlStartTime));
System.out.println("Sum:"+finalRes);
}
}
功能评价
此盘算的总实行工夫在120,000毫秒到128,000毫秒之间。假如在不分化义务的情形下在当地运转一样的义务,实行工夫将在183,241到237,641毫秒之间。
最后,主义务包含盘算从1到10^7的一切整数的平方根之和。为测试功能,我将盘算局限扩展到10^8,终极扩展到10^9。
跟着义务量的增添,远程并行实行和当地实行所需工夫的不同也愈来愈分明。这就是说,当实行年夜型义务时,远程并行实行损耗的工夫较少。远程并行实行其实不合适小型义务,由于呆板间通讯的体系开支不容无视。跟着义务量的增添,呆板间通讯的开支与在单个呆板上实行全体义务的开支比拟渐渐变得微乎其微。因而,我得出以下结论:伪远程线程体系能很好地完成必要举行大批盘算的义务。
利用伪远程线程有哪些长处?
由于伪远程线程是一种基于Java的体系,它能够用于完成包括多种操纵体系的集群,或异构集群。利用伪远程线程,您就制止了转换原有C/C++代码的贫苦,并且还能使用Java尺度库及其各类扩大库。别的,伪远程线程使您不用体贴内存办理。固然,其弱点就是体系功能与JRE功能间接相干。
开展偏向
如今相称多的贸易使用程序都是用Java平台创立的,并思索到为了使用并行性必要转换原本的C/C++代码的实践坚苦,如今多是基于Java的超等盘算进进贸易范畴的时分了。在入手下手创立基于Java的使用程序时就将并行性和负载平衡思索在内是个不错的初步。
互联网就是异构集群的一个很好的例子,因而伪远程线程能够在因特网中部署,将Web转换为一个单一的、基于Java的超等盘算机(要懂得这一观点的细节,请参阅参考资本)。但是,从实践使用动身,您应注重到在一个专门实行单一义务的同构集群中将取得最好了局。
最初,从一样平常使用动身,伪远程线程使得将局域网(LAN)--诸如校园网和家庭网--转换为微型的超等盘算机变得相称复杂。这就是Beowulf体系创始的用法。有了伪远程线程,Java编程职员也能够创立本人的超等盘算机了。
参考资本
"Linuxclusteringcornucopia"(developerWorks,2000年5月)为您指导迷津,让您懂得以后Linux上可用的开放源码集群办理计划和保密源码集群办理计划。
要懂得关于散布式操纵体系的具体信息,请检察AndrewS.Tanenbaum的ModernOperatingSystems(PrenticeHall出书公司,1992年2月)。
要懂得关于并行编程的具体信息,请参阅GregoryV.Wilson的PracticalParallelProgramming(麻省理工学院出书社,1995年12月)。
要进一步了解集群,请参阅ScalableComputingLaboratory的ClusterCookbook。
有关使用Java手艺和Web举行超等盘算的深层切磋,请参阅LaurenceVanhelsuw的"CreateyourownsupercomputerwithJava?"
(JavaWorld,1997年1月)。
Linuxdocument.tionProject托管着BeowulfHOWTO文档。
会见Beowulf网站,以懂得Beowulf项目标具体信息。
请参阅关于OakRidge国度实行室出名的StoneSouperComputer的具体信息。
Aspen体系公司是今朝供应定制集群办理计划的多数厂商之一。
ruby里有这些工具吗?又要简单多少?我没有用过这两门语言,我估计在这些语言力没有很统一的这种标准,或者根本就没有提供。 |
|