快捷搜索:

构建自己的基于 Java 的超级计算机

作者:Thadomal Shahani

(本文选自IBM developerWorks中文网站)

假如您曾想过构建自己的超级谋略机,但却对用 C 说话进行并行编程望而却步,那么伪远程线程可以帮您办理这一问题。这种获奖的 Java 编程模型极大年夜地简化了集群上的并行编程,并使超级谋略走出实验室,使每一位 Java 法度榜样员都能应用它。

在以前的三年里,并行集群已在改变着超级谋略的面目。一旦代价数百万美元的单体机占了主导,并行集群很快就会成为超级谋略机的选择。可以想像获得,开放源码圈内的飞腾热心已导致孕育发生了数百 -- 假如不是数千的话 -- 并行集群项目。第一个同时也是最闻名的开放源码集群系统是 Beowulf。在 NASA 辅助下,由 Thomas Sterling 和 Donald Becker 在 1994 年宣布的 Beowulf,开始是作为一个 16 节点演示集群推出的。本日,Beowulf 已稀有百种实现,从 Oak Ridge 国家实验室的 Stone SouperComputer 到 Aspen 系统公司的定制构建的商业性集群(请参阅参考资本)。

对 Java 法度榜样员晦气的是,多半集群系统都是环抱基于 C 说话的软件消息通报 API ? 如消息通报接口(MPI)或并行虚拟机(PVM)? 来实现的。用 C 说话进行并行编程不是件轻易的事,是以我设计了一个替代规划。本文将阐明若何综合运用 Java 线程和 Java 远程措施调用(RMI)来创建自己的基于 Java 的超级谋略机。

请留意,本文假定您有 Java 线程和 RMI 的利用常识。

超级谋略机内有什么?

超级谋略机的定义是:由八个或更多的节点组成、作为单个高机能机械事情的集群。基于 Java 的超级谋略机包孕一个功课调整器和随意率性数量的运行办事器(也称为主机)。功课调整器天生多个线程,每个线程包孕履行不合子义务的代码。各个线程将其代码迁移到不合的运行办事器上。然后,每个运行办事器履行迁移给它的代码并将结果返回给功课调整器。着末,功课调整器将各个线程的结果组合起来。

这种并行集群系统之以是被称为伪远程线程,是由于线程是在功课调整器上调整的,但线程内的代码却是在远程谋略机上履行的。

该系统有哪些组件?

组件一词是指组成“伪远程线程”并行集群系统的逻辑模块。该系统包孕以下组件:

Job dispatcher(功课调整器) 是履行节制的机械。它天生不合的线程,每个线程都包孕此集群要处置惩罚的主义务的一个子义务。每个线程内的代码都被发送到一台远程谋略机去履行。线程在功课调整器上调整,以是理论上讲,该机械不应该用于履行任何子义务。

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。

运行办事器在启动时接通功课调整器,并看护功课调整器它已筹备就绪,可以吸收要履行的义务了。

一个谋略示例

现在该测试这一模型了。以下谋略示例应用两台谋略机并交运行。一台是运行 Windows 98 的 333 MHz Pentium II 谋略机,另一台是运行 Windows 2000 专业版的 500 MHz Pentium III 谋略机。

为了谋略从 1 到 10^9 的所有整数的平方根之和,我创建了 Sqrt 类,它谋略 dblStart 和 dblEnd 之间所有整数的平方根之和。

Sqrt 实现 JobCodeInt 接口,是以也实现了 jobCode() 措施。在 jobCode() 措施中,我定义了完成这一谋略的代码。

构造函数用于将数据通报给 Sqrt 类,并初始化功课调整器上的所有本地资本。必须将要谋略其平方根之和的整数的起止点发送给构造函数。清单 1 是 Sqrt 类的定义

清单 1. 定义 Sqrt 类

//Sqrt 类谋略 dblStart 和 dblEnd 之间的所有整数的平方根之和。

//谋略在 jobCode() 措施内完成

//该类实现 JobCodeInt 接口,且实今世码位于 jobCode() 措施内

//在构造函数中将数据通报给该类,并初始化功课调整器上的本地资本。

//本例中,要谋略其平方根之和的整数序列的起止点被发送给 Sqrt 类

public class Sqrt implements JobCodeInt

{

double dblStart, dblEnd, dblPartialSum;

public Sqrt(double Start,double End)

{

dblStart = Start;

dblEnd = End;

}

public Object jobCode()

{

dblPartialSum = 0;

for(double i=dblStart;i<=dblEnd;i++)

//可调用标准的 Java 函数和工具。

dblPartialSum += Math.sqrt(i);

//返回结果,一个标准 Java 类的工具。

return (new Double(dblPartialSum));

}

}

JobDispatcher 类创建 Sqrt 类的两个实例。然后分化主义务,将一项子义务分配给一个 Sqrt 工具(Sqrt1),并将余下的子义务分配给另一个 Sqrt 工具(Sqrt2)。接下来,JobDispatcher 创建 PseudoRemThr 类的两个工具,并将 Sqrt 工具作为参数分手通报给它们。接下来就等待线程履行。

一旦线程履行完毕,就可从每个 PseudoRemThr 实例得到部分结果。将各部分结果组合起来即可获得最遣散果,如清单 2 所示。

清单 2. 事情中的 JobDispatcher

//此类可以命名为您选择的任何名称

//这里选用 JobDispatcher 只是为了方便

public class JobDispatcher

{

public static void main(String args[])

{

double fin = 10000000; //代表 10^9

double finByTen = fin/10; //代表 10^8

long nlStartTime = System.currentTimeMillis();

//范围从 1 到 3*10^8

Sqrt sqrt1 = new Sqrt(1,finByTen*3);

//范围从 ((3*10^8)+1) 到 10^9

Sqrt sqrt2 = new Sqrt((finByTen*3)+1,fin);

//以下创建 PseudoRemThr 类的两个实例。

//此构造函数的参数如下所示。

//第一个参数:代表子义务的某个类的实例

//第二个参数:履行这一子义务的远程主机

//第三个参数:PseudoRemThr 实例的描述性名称。

PseudoRemThr psr1 = new

PseudoRemThr(sqrt1,"//192.168.1.1:3333/","Win98");

PseudoRemThr psr2 = new

PseudoRemThr(sqrt2,"//192.168.1.2:3333/","Win2K");

psr1.waitForResult(); //等待履行停止

//获取每个线程的结果

Double res1 = (Double)psr1.getResult();

Double res2 = (Double)psr2.getResult();

double finalRes = res1.doubleValue() + res2.doubleValue();

long nlEndTime = System.currentTimeMillis();

System.out.println("Total time taken: " + (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 编程职员也可以创建自己的超级谋略机了。

参考资本

"Linux clustering cornucopia"(developerWorks, 2000 年 5 月)为您辅导迷津,让您懂得当前 Linux 上可用的开放源码集群办理规划和保密源码集群办理规划。

要懂得关于散播式操作系统的具体信息,请查看 Andrew S. Tanenbaum 的 Modern Operating Systems(Prentice Hall 出版公司,1992 年 2 月)。

要懂得关于并行编程的具体信息,请参阅 Gregory V. Wilson 的 Practical Parallel Programming(麻省理工学院出版社,1995 年 12 月)。

要进一步理解集群,请参阅 Scalable Computing Laboratory 的 Cluster Cookbook。

有关运用 Java 技巧和 Web 进行超级谋略的深层探究,请参阅 Laurence Vanhelsuw 的 "Create your own supercomputer with Java?"(JavaWorld, 1997 年 1 月)。

Linux Documentation Project 托管着 Beowulf HOWTO 文档。

造访 Beowulf 网站,以懂得 Beowulf 项目的具体信息。

请参阅关于 Oak Ridge 国家实验室闻名的 Stone SouperComputer 的具体信息。

Aspen 系统公司是今朝供给定制集群办理规划的少数厂商之一。

您可能还会对下面的文章感兴趣: