• 沒有找到結果。

2-1 系統架構

系統採用免費的作業系統 Linux,並使用免費的 mpich 與排程軟體來自行建置。下 圖為PC 叢集式電腦的簡易架構圖:

Switch/HUB Server

node1 node2 node3 node4 node5 node6

Fig 2-1 PC Cluster 架構圖

這套簡易的叢集式電腦系統,包含了一台 Server 控制與分配計算 job;六台計算 nodes,提供平行計算能力,這些機器是本校電算中心電腦教室經過設備更新後,整理 出功能完整的舊電腦,而 Switch/HUB 也是電算中心網路服務組目前堪用的設備。系統 可以提供平行化程式撰寫之能力,並進行程式正確性之測試。本系統最大的優點是可擴 充、更新,日後若想建立更強大的系統,只要新增或更換設備即可。在完成PC Cluster 建置後,首先要進行系統環境的測試與調整,因為設備的差異性,必須針對每台機器進 行軟、硬體調整,找出最佳的網路傳輸參數值。

基本上 PC Cluster(叢集式電腦)可以視做將一個大的資料(如陣列)切割成為許多小 資料,分散到不同 CPU 去做運算的工作,最後再將這些資料集中起來,得到結果。PC Cluster 的建立,主要是因為超級電腦建置管理不易,轉而使用多台 CPU 來堆積計算效 能,因此有人號稱 PC Cluster 是「螞蟻雄兵」,可以積沙成塔,匯聚計算能力的工具,

下圖就是本計劃所完成的PC Cluster (目前放置於電算中心 3F)。

一般而言,在科學計算的領域上,大多會選擇C 或者 Fortran 語言來撰寫程式碼,

本計劃則使用Fortran 語言,最主要的原因是 Fortran 程式碼易懂好學,非常容易上手,

加上網路上隨手可得的外掛函式庫lib,因此以 Fortran 為主來開發相關程式。

Fig 2-2 PC Cluster @ MUST

2-2 叢集式電腦程式設計的技巧

1. 清楚的定義變數名稱:一個程式可能交由許多人來撰寫,如果變數定義不夠清 楚,在程式做組合的時候,就會造成困難。

2. 撰寫程式由上而下:先由宏觀的角度建構程式架構,然後再來細部分工到主程 式、副程式內。

3. 善用流程圖:利用流程圖來控制程式的流程走向,可以減少程式邏輯的錯誤。

4. 可讀性的提高:一個好的程式應該多多利用「縮排」、「空行」、「註解」來增加可 閱讀性,以避免日後維護時造成困擾。

5. 適當地使用副程式:一般在撰寫大型程式時,可以適當地使用副程式,除了可以 確保主程式的程序流暢以外,更可以將副程式的工作分配給其他人撰寫。

6. 考量使用者的感受:程式撰寫者往往只依照自己的感覺設計介面,沒有考慮到使 用者的輸入、輸出感覺,所以程式完成前需要做一些測試。

7. 完工後不要忘記撰寫手冊:清楚地寫下操作步驟、變數名稱…等等細節,有助於 幫助操作者或者自己日後的維護工作。

2-2 Fortran 程式撰寫技巧 2-2-1 程式撰寫與編譯

請在文字編輯器(在 client 端可用記事本或 UltraEDIT; 伺服器可用 vi 或 pico)輸入以

下「文字」:

c...程式的開始

PROGRAM EX1

c...關閉所有預設的變數, 例如 I,J,K IMPLICIT NONE

c...設定 AGE 為整數變數 INTEGER AGE

c...在螢幕顯示 How old are you?

WRITE(*,*) 'How old are you?' c...讀取 AGE 變數

READ(*,*) AGE

c...在螢幕顯示 You are xx years old

WRITE(*,*) 'You are', AGE, ' years old' c...程式結束

STOP c...主程式碼結束 END 注意事項:

1. 如果在 Linux 系統下按 Backspace 鍵會出現亂碼,請使用 ctrl + Backspace 應該就可 以解決了

2. 有些編譯器會錯認 Tab 鍵,所以請儘量使用空白鍵來替代 Tab 鍵(也就是 Fortran 每 行程式碼前面須空6 個字元)

3. 在 Unix Like 執行單一程式的方法為 ./程式名稱 ( 如 ./test.exe )

這是因為避免發生駭客攻擊漏洞,前方的 . 代表目前資料夾

4. 連結上遠端伺服器可以使用 telnet 指令,善用 Windows 上快速鍵:複製 Ctrl + Insert 與 貼上 Shift + Insert

然後利用FTP 上傳到伺服器後,下指令

[maty@server1 maty]$ mpif77 -o ex1.exe ex1.f

其中mpif77 是編譯程式;ex1.exe 是預計產生的執行檔案;ex1.f 則是執行檔案 如果沒有發生任何的錯誤訊息,執行程式的方法為

[maty@server1 maty]$ ./ex1.exe

我們可以發現電腦會詢問問題,當我們輸入數字之後,並且按下Enter,可以得到 答案。

2-2-2 流程控制

請在文字編輯軟體輸入以下「文字」,並完成上傳以及編譯執行檔的動作:

PROGRAM EX2 IMPLICIT NONE c

c...weight 體重; age 年齡 INTEGER age,weight c

c...輸入年齡與體重

WRITE(*,*) 'Please input your age?' READ(*,*) age

WRITE(*,*) 'Please input your weight?' READ(*,*) weight

c

c...過濾出年紀小於 30 歲,體重卻超過 100 公斤者 IF ((age .LT. 30) .AND. (weight .GT. 100)) THEN WRITE(*,*) 'You are overweighted!'

ELSE

WRITE(*,*) 'Your weight is under control' END IF

c

STOP END

請注意Fortran 數學運算:

+ 加法 ; - 減法 ; * 乘法 ; / 除法 ; ** 乘冪 計算優先順序:( )Æ **Æ */+-

在這個CASE,輸入以下的數值,會由不同的結果:

age weight WRITE(*,*) NOTE

30 100 Your weight is under control! age 與 weight 皆不符合 30 101 Your weight is under control! 僅 weight 符合

29 100 Your weight is under control! 僅 age 符合

29 101 You are overweighted! age 與 weight 皆符合

在這裡我們使用了一個IF…THEN…ELSE 函數,主要功能是用來進行流程控 制,所使用的邏輯判斷運算如下所列:

.EQ. 等於 .GE. 大於等於

.NE. 不等於 .LT. 小於

.GT. 大於 .LE. 小於等於

若搭配.AND.(交集)、 .OR.(聯集)、 .NOT. (邏輯反向) 會有更多的「妙用」。

2-2-3 迴圈

請在文字編輯軟體輸入以下「文字」,並完成上傳以及編譯執行檔的動作:

PROGRAM EX3 IMPLICIT NONE c

c...定義雙精準度的陣列 A REAL*8 A(3,3) c...定義整數參數

INTEGER I,J,ROW,COL c...指定固定參數

PARAMETER (ROW=3,COL=3) c

c...將陣列 A 放入變數 DO 10 I = 1, ROW DO 10 J = 1, COL A(I,J)= I*J*1.d0 10 CONTINUE

c

c...在螢幕顯示陣列 A DO 20 I = 1, ROW DO 20 J = 1, COL WRITE(*,*) A(I,J) 20 CONTINUE

c

STOP END

請注意Fortran 的浮點數 real 有兩種型態,分別是

REAL*4 單精確度:在個人電腦上佔了 32bits的長度,有效位數 6-8 位,可紀錄最 大值為3.4x1038,最小值則為1.18x10-38

REAL*8 雙精確度:長度為 64bits,有效位數 15-16 位,可紀錄最大值為 1.79x10308, 最小值則為2.23x10-308

在這個CASE,得到以下結果:

[maty@server1 maty]$ ./ex3.exe 1.000000000000000 2.000000000000000 3.000000000000000 2.000000000000000 4.000000000000000 6.000000000000000 3.000000000000000 6.000000000000000 9.000000000000000

首先,當程式流程經過DO 10 I = 1, ROW 時,此時 I 等於 1,而 I 的變化值在 1 至 3 之間(因為 ROW 已經是固定參數 3)。接下來 J=1,COL 時,狀況跟 I 是相同的,變化值 也是1 至 3 之間(因為 COL 已經是固定參數 3)。

將I 與 J 帶入到 A(I,J)=I*J*1.d0 中 (其中 1.d0 的意思是 1x100),I=1、J=1,因此 A(1,1)就等於 1*1*1.d0。

程式繼續執行,遇到10 CONTINUE,意思就是回到最近的編號 10 的起點繼續執行,

最近的編號10 的起點就是 DO 10 J = 1, COL。此時 J 加 1 等於 2,但是 I 仍然等於 1。

帶入到A(I,J)=I*J*1.d0 中得到 A(1,2)=1*2*1.d0。如此類推,可得 A(1,3)=1*3*1.d0。

接下來,J 的範圍已至最大值,因此 10 CONTINUE 就選擇回到 DO 10 I = 1, ROW。

此時I 就變成 2,而 J 的內迴圈變化值仍是由 1 至 3:A(2,1)=2*1*1d0;A(2,2)=2*2*1d0 以及A(2,3)=2*3*1d0。以此類推填滿至 A(3,3)。

2-2-4 副程式及開檔案

請在文字編輯軟體輸入以下「文字」,並完成上傳以及編譯執行檔的動作:

PROGRAM EX4 IMPLICIT NONE c

c...定義雙精準度的陣列 A REAL*8 A(3,3) c...定義整數參數

INTEGER ROW,COL c...指定固定參數

PARAMETER (ROW=3,COL=3) c

c...呼叫副程式 1,寫入陣列 CALL PUTIT(A,ROW,COL) c...呼叫副程式 2,寫入檔案

CALL SAVEIT(A,ROW,COL) c

STOP END c

c

c...副程式 1: 寫入陣列

SUBROUTINE PUTIT(A,ROW,COL) IMPLICIT NONE

INTEGER I,J,ROW,COL REAL*8 A(3,3)

c...將陣列 A 放入變數 DO 10 I = 1, ROW DO 10 J = 1, COL

A(I,J)= I*J*1.d0 10 CONTINUE c

RETURN END c

c...副程式 2: 寫入檔案

SUBROUTINE SAVEIT(A,ROW,COL) IMPLICIT NONE

INTEGER I,J,ROW,COL REAL*8 A(3,3)

c...開啟檔案 HELLO.TXT, 讀取編號為 10 OPEN(10, FILE='HELLO.TXT') c...將陣列 A 寫入 HELLO.TXT 的檔案內 DO 10 I = 1, ROW

DO 10 J = 1, COL WRITE(10,*) A(I,J) 10 CONTINUE

c...關閉檔案 HELLO.TXT CLOSE(10) c

RETURN END

接續左半邊程式碼

我們可以發現其實副程式的寫法類似主程式,一樣要進行宣告變數的動作,由主程 式連結到副程式的方法就是使用call「副程式名稱」,其中必須包括了彼此之間要互相傳

遞的變數與參數。

檔案的開啟練習在副程式2 當中,利用 OPEN 的指令開啟檔案,開啟時必須指定一 個讀取編號,由於一般內定的輸出編號,例如螢幕…等等,編號大多在 10 以內,所以 自行所選擇的讀取編號建議大於10 以上。

2-3 Cluster 程式撰寫技巧 2-3-1 PC Cluster 介紹與指令

PC Cluster 建置當中,最主要就是利用了 NFS(Network File Systems)與 NIS(Network Information System)的網路服務,將使用者帳號與磁碟空間結合起來,透過彼此機器的 相互信任(rsh),並且安裝平行計算 MPI(Message Passing Interface)的功能,就可以完成一 組PC Cluster 的建置,若是需要加上管理功能,則必須再安裝 DQS (Distributed Queueing System)。以下是幾個常用的指令,包括 Linux、mpif77、mpirun 與 DQS:

Linux 指令

‹ 檢視檔案 指令:ls

例如:ls –l (檢視所有的檔案,包括隱藏檔案)

ls -l | more (使用 |指向 至 more,超過一個畫面的長度就先暫停下來)

‹ 更換資料夾 指令:cd

例如:cd work (進入 work 資料夾)

‹ 建立資料夾

指令:mkdir 資料夾名稱

例如: mkdir hello (建立 hello 資料夾,注意:在 Unix Like 的 OS,大小寫的意義 不同)

‹ 刪除檔案

指令:rm –rf 檔案名稱或資料夾

例如: rm –rf for* (強制刪除所有以 for 開頭的檔案與資料夾)

‹ 複製檔案

指令:cp 檔案名稱 複製的新檔案名稱

例如:cp -r work work1 (複製 work 資料夾到新的資料夾 work1)

‹ 移動檔案

指令:mv 檔案名稱 新的位置

例如:mv test.f ./work (將檔案 test.f 移動 至 目前資料夾下的 work 資料夾內)

‹ 查詢目前已經使用的硬碟空間 指令:du 資料夾路徑

例如:du –s (預設是目前所在的資料夾,顯示該資料夾下 檔案所佔的硬碟空間)

‹ 查詢目前硬碟所剩下的空間 指令:df

例如:df –k (以 k bytes 顯示,預設值)

‹ 更改檔案屬性權限

指令:chmod □□□ 檔案或資料夾名稱

例如:chmod 755 test.cmd (將 test.cmd 檔案屬性改成 755:擁有者可讀寫執行、

群組及全體使用者可讀、執行,不可寫入) 請注意:

A B C 分別代表A擁有者;B群組;C全體使用者 的權限,每一個位置又有 三種不同的權限[rwx],開啟為 1 關閉為 0。以A擁有者為例,若只給執行(x)與讀取 (r)的權限,不給寫入(w)的權限,則為[1x22+0x21+1x20]=5

‹ 更改某個檔案或目錄的擁有者

指令:chown 擁有者 檔案或資料夾名稱

例如:chown –R maty test (將 test 資料夾的擁有者改成 maty,且在 test 資料 夾內 所有的檔案與資料夾的擁有者都一併都改成 maty)

‹ 更改某個檔案或目錄的擁有群組

指令:chgrp 擁有群組 檔案或資料夾名稱

例如:chown –R maty test (將 test 資料夾的擁有群組改成 maty,且在 test 資 料夾內 所有的檔案與資料夾的擁有群組都一併都改成 maty)

mpif77 與 mpirun

‹ 編譯

指令:mpif77 –o 執行檔檔案名稱 原始碼程式名稱 例如:mpif77 –o ex1.exe ex1.f

‹ 直接執行平行化程式(不經過 DQS 安排管理)

指令:mpirun –np cpu 執行個數 執行檔案名稱 例如:mpirun -np 4 ex1.exe

注意事項:CPU0 通常就是指下指令與資料讀取、回存的電腦,也就是 Server

DQS 管理功能

‹ 檢查目前 DQS 狀態

指令為qstat332 (只顯示目前有工作的 CPU)

指令為qstat332 –f (顯示所有 CPU,無論是否有工作) 以下為DQS 狀態範例:

[maty@server1 maty]$ qstat332 -f

Queue Name Queue Type Quan Load State --- --- --- --- --- node001 batch 0/1 0.01 dr DISABLED node002 batch 0/1 0.00 er UP

node003 batch 0/1 0.00 er UP node004 batch 0/1 0.00 er UP node005 batch 0/1 0.00 er UP node006 batch 0/1 0.00 er UP node007 batch 0/1 0.00 er UP

node008 batch 0/1 0.00 eru UNKNOWN node009 batch 0/1 0.00 eru UNKNOWN node010 batch 0/1 0.00 eru UNKNOWN node011 batch 0/1 0.00 eru UNKNOWN node012 batch 0/1 0.00 eru UNKNOWN node013 batch 0/1 0.00 er UP

node014 batch 0/1 0.00 er UP node015 batch 0/1 0.00 er UP node016 batch 0/1 0.00 er UP

狀態說明:

dr DISABLED 代表CPU 目前被指定為不工作(Shutdown) er UP 代表CPU 目前可以工作(RUNNING)

eru UNKNOWN 代表CPU 目前狀態不明(未開機或者 DQS 未啟動)

所 以 上 表 內 node001 為不工作(nolocal);node008, node009, node010, node011, node012 未開機;其餘電腦可以工作。換句話說,可以有 10 台 CPU 服務,如果使 用者的程式是需要5 台 CPU,那麼可以同時安排兩個使用者執行程式而彼此不受干 擾。

‹ 安排工作

指令為qsub332 dqs_job_shell

其中dqs_job_shell 為自行撰寫的 DQS 程序檔,參考範例 dqs.sh,如下:

#!/bin/csh

#$ -cwd

#$ -l qty.eq.5

#$ -N project1

#$ -A maty

/usr/local/package/mpich/bin/mpirun -np $NUM_HOSTS -machinefile $HOSTS_FILE prog

其中 #!/bin/csh 表示為 C shell script

#$-cwd 表示在目前的目錄執行(預設是 home directory)

#$-l qty.eq.5 需要5 個 CPU,qty 是 quantity 縮寫,eq 則是 equation 的縮寫

#$-N project1 submit job 的工作名稱(Name)為 project1

#$-A maty 使用者帳號(Account),本範例為 maty

$NUM_HOSTS 代表目前需求的CPU 數量(來自 qty.eq.5 設定)

$HOSTS_FILE DQS 安排這項工作的 node list

執行時直接在命令列下qsub332 dqs.sh 即可,如下所示:

執行時直接在命令列下qsub332 dqs.sh 即可,如下所示:

相關文件