麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

構建自己的基于 Java 的超級計算機

2019-11-18 13:17:15
字體:
來源:轉載
供稿:網友

  對 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,"http://192.168.1.1:3333/","Win98");
  PseudoRemThr psr2 = new
  PseudoRemThr(sqrt2,"http://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.  System.out.println("Sum: " + finalRes);
  }
  }
  
  性能評價
  此計算的總執行時間在 120,000 毫秒到 128,000 毫秒之間。假如在不分解任務的情況下在本地運行同樣的任務,執行時間將在 183,241 到 237,641 毫秒之間。
  
  最初,主任務包括計算從 1 到 10^7 的所有整數的平方根之和。為測試性能,我將計算范圍擴大到 10^8,最終擴大到 10^9。
  
  隨著任務量的增加,遠程并行執行和本地執行所需時間的差別也越來越明顯。這就是說,當執行大型任務時,遠程并行執行消耗的時間較少。遠程并行執行并不適合小型任務,因為機器間通信的系統開銷不容忽視。隨著任務量的增加,機器間通信的開銷與在單個機器上執行全部任務的開銷相比逐漸變得微不足道。因此,我得出以下結論:偽遠程線程系統能很好地完成需要進行大量計算的任務。
  
  使用偽遠程線

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 懂色av懂色aⅴ精彩av | 中文字幕在线日韩 | 国产99视频在线观看 | 九九热在线免费观看视频 | 91 在线 | av在线播放电影 | 成人免费在线观看视频 | 色视频在线观看 | 中文字幕亚洲情99在线 | 久久久久电影网站 | 精品亚洲在线 | 91丨九色丨国产在线观看 | 国产精品久久久久久久久久久久午夜 | 日本视频在线免费观看 | 亚洲成人播放 | 欧美国产一区二区三区 | 欧美视频黄色 | 成人不卡在线观看 | 国产亚洲精品久久久久婷婷瑜伽 | 91精品国产免费久久 | 嫩呦国产一区二区三区av | 亚洲va久久久噜噜噜久久男同 | 媚药按摩痉挛w中文字幕 | 久久中文字幕在线观看 | 久久6国产 | 密室逃脱第一季免费观看完整在线 | 国产精品免费成人 | 91av网址 | 亚洲3p激情在线观看 | 今井夏帆av一区二区 | 依人在线视频 | 免费黄色在线电影 | 黄色男女视频 | 羞羞网站| av在线免费看片 | 欧美精品日日鲁夜夜添 | 亚洲精中文字幕二区三区 | 91经典视频| 欧美成年视频 | 免费看欧美一级特黄a大片 久久免费视频一区二区三区 | 成人啪啪18免费网站 |