950 likes | 1.23k Views
PC クラスタを作ろう!!. 廣安 知之 同志社大学 工学部 知識工学科 tomo@is.doshisha.ac.jp. Cluster. clus · ter n. Ⅰ 〔 ブドウ・サクランボ・フジの花などの 〕 房 (ふさ) 〔 of 〕a cluster of grapes 一房のブドウ . Ⅱ 〔 同種類のもの・人の 〕 群れ , 集団 〔 of 〕a cluster of spectators 一団の観客 . a cluster of butterflies チョウの群れ .
E N D
PCクラスタを作ろう!! 廣安 知之 同志社大学 工学部 知識工学科 tomo@is.doshisha.ac.jp
Cluster clus·tern. Ⅰ 〔ブドウ・サクランボ・フジの花などの〕房(ふさ) 〔of〕a cluster of grapes 一房のブドウ. Ⅱ 〔同種類のもの・人の〕群れ, 集団 〔of〕a cluster of spectators 一団の観客. a cluster of butterflies チョウの群れ. a cluster of stars 星団. in a cluster(一つに)かたまって, 群れをなして. in clustersいくつもの群れをなして, かたまりになって. New College English-Japanese Dictionary, 6th edition (C) Kenkyusha Ltd. 1967,1994,1998
PCクラスタ 並列計算機
このチュートリアル講座では... PCクラスタという並列計算機 計算機の作り方 ハードウエア ソフトウエア 並列計算の仕方 一般的なプログラムの作成 進化的計算(GAなど)の並列モデル
でも本当は教えたくない!? • 並列処理の研究には明日はないかもしれないが,経済問題,バイオインフォマティクスとならんで,並列アプリケーションには夢がある.(閉塞を打破しよう...情報処理学会誌 2001.7,8) 導入が極めて簡単(大規模・高度なシステムは難しい)
並列アプリケーションには明日がある!? 高速に処理が可能 創発アルゴリズム(特に進化的計算アルゴリズム)は確実に高速化が可能 計算パラダイムが変わる?(P2Pなど) 創発アルゴリズム(特に進化的計算アルゴリズム)には秘策がある
はずかしい並列(embarrassing parallel) P P P P P P P P パラメトリックサーチ
P P P P 初期解のbroadcast 解の収集・ベスト解の選択 創発アルゴリズム(特に進化的計算アルゴリズム)の秘策 • ある探索アルゴリズムで25%の確率で解が発見できる場合 • 並列アルゴリズムによって100%の確率で解が発見可能!!
何故並列処理を行わなければならないのか? 高速に処理をおこなわなければならない 計算コストが高い 繰り返しを多く必要とする 大規模な問題
進化的計算手法 Features 生物の遺伝と進化 様々な問題に比較的簡単に適用可能 計算負荷が高い 個体数が多い 1つの仕事はサブタスクに分割可能 High Performance Computing (HA)
何故並列処理を行わなければならないのか? 特に進化的計算の場合は威力を発揮(後で詳しく説明)
何故並列処理を行わなければならないのか? ex. SETI@home Project rc5 Intel Philanthoropic P2P Program 計算資源は余っている. 研究室のパソコン 実習室・演習室のパソコン 景気刺激対策で導入された大型計算機 その他 グローバルコンピューティング インターネット接続による大規模システム P2P NapsterやGnutellaを代表とする分散システム 計算パラダイムの変化
並列処理の必要性はわかったが何故PCクラスタなのか?並列処理の必要性はわかったが何故PCクラスタなのか?
http://www.top500.org Top500 Ranking Name # Proc Rmax (Gflops) 1 8192 7226 ASCI White 2526 2 SP Power3 2528 9632 3 ASCI Red 2379 4 ASCI Blue-Pacific 5808 2144 5 SR8000/MPP 1152 1709 Parallel Computers
Commodity Hardware Networking Internet Lan Wan Gigabit cable less etc. CPU Pentium Alpha Power etc. PCs + Networking PC Clusters
なぜPCクラスターなのか? 高い性能 低コスト 簡単なセットアップ 簡単な利用 占有可能 hardware Commodity Off-the-shelf Software Open source Free ware Peopleware 大学の学生,助手,講師 研究所のおたく
http://www.top500.org Top500 Ranking Name # Proc Rmax (Gflops) 36 1024 SCore III 547.9 512.4 42 CPlant Cluster 1000 512 102 LosLobos 237 528 156 CLIC PIII 143.3 389 ABACUS Cluster 520 80.8 439 Presto III 104 77.4
PCクラスタ 8nodes + gateway(file server) Fast Ethernet Switching Hub 150万
何を準備すれば良いのか? Normal PCs Hardware CPU memory motherboard hard disc case network card cable hub
何を準備すれば良いのか? Software OS tools Editor Compiler Parallel Library
ソケット 「接続の端点」 意味: コンピュータとTCP/IPを つなぐ出入り口 ソケット TCP/IP
ソケット通信 サーバプログラム ソケットを用意して接続要求を待つ クライアントプログラム ソケットを用意して サーバに接続要求を行う • ソケットを使って通信を行うには • 2つのプログラムが必要
ソケット通信とは 接続待ち 接続待ちのサーバを クライアントが探す サーバを探す サーバ側 クライアント側
ソケット通信とは 接続を受信 サーバが見つかったら 接続して通信 サーバを見つけて接続 サーバ側 クライアント側
メッセージパッシングライブラリ PVM (Parallel Virtual Machine) http://www.epm.ornl.gov/pvm/pvm_home.html PVM was developed at Oak Ridge National Laboratory and the University of Tennessee. MPI (Message Passing Interface) http://www-unix.mcs.anl.gov/mpi/index.html MPI is an API of message passing. 1992: MPI forum 1994 MPI 1 1887 MPI 2
MPIの実装 Free Implementation MPICH : LAM: WMPI : Windows 95,NT CHIMP/MPI MPI Light Bender Implementation Implementations of parallel computers MPI/PRO :
クラスタの構築の手順 複数台のPCを用意する PCをつなげる OSとtoolをインストールする 開発toolと並列ライブラリをインストール
OS/tools Linux GNU Compiler, GDB rsh
MPICH/LAMのインストール # rpm –ivh lam-6.3.3b28-1.i386.rpm # rpm –ivh mpich-1.2.0-5.i386.rpm # dpkg –i lam2_6.3.2-3.deb # dpkg –i mpich_1.1.2-11.deb # apt-get install lam2 # apt-get install mpich
ソケット通信の流れ 1 ソケット生成 (socket) ソケット生成 (socket) クライアント サーバ
ソケット通信の流れ 2 サーバを探す (gethostbyname) 接続の準備 (bind/listen) クライアント サーバ
ソケット通信の流れ 3 接続要求 (connect) 接続受理 (accept) OK! クライアント サーバ
ソケット通信の流れ 4 通信 (send/recv) 通信 (send/recv) こんにちわ こんにちわ クライアント サーバ
ソケット通信の全体の流れ ソケット生成(socket) サーバを探す (gethostbyname) 接続要求(connect) データ送受信(send/recv) ソケットを閉じる(close) クライアント サーバ ソケット生成(socket) 接続の準備(bind) 接続待機(listen) 識別情報 接続受信(accept) データ送受信(send/recv) ソケットを閉じる(close)
クライアントプログラム(C) //client.c #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netdb.h> #include<string.h> #define PORT (u_short)10000 #define BUF_LEN 100 char hostname[]="localhost"; char buf[BUF_LEN]; main() { struct hostent *servhost; struct sockaddr_in server; int s; servhost = gethostbyname(hostname); bzero((char *)&server,sizeof(server)); server.sin_family = AF_INET; server.sin_port = PORT; bcopy(servhost->h_addr, (char *)&server.sin_addr,servhost->h_length); s = socket(AF_INET,SOCK_STREAM,0); connect(s,(void *)&server,sizeof(server)); read(s,buf,BUF_LEN); printf(buf); close(s); }
サーバプログラム(C) //server.c #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netdb.h> #include<string.h> #define PORT (u_short)10000 char hostname[] = "localhost"; main() { struct hostent *myhost; struct sockaddr_in me; int s_waiting, s; char msg[] = "Hello World!!\n"; myhost = gethostbyname(hostname); bzero((char *)&me, sizeof(me)); me.sin_family = AF_INET; me.sin_port = PORT; bcopy(myhost->h_addr, (char *)&me.sin_addr,myhost->h_length); s_waiting = socket(AF_INET,SOCK_STREAM,0); bind(s_waiting,(void *)&me,sizeof(me)); listen(s_waiting, 1); s = accept(s_waiting, NULL, NULL); close(s_waiting); write(s, msg, strlen(msg)); close(s); }
クライアントプログラム(Java) import java.io.*; import java.net.*; import java.lang.*; public class Client{ public static void main( String[] args ){ try{ //ソケットを作成 String host="localhost"; Socket socket = new Socket( host, 10000 ); //入力ストリームを作成 DataInputStream is = new DataInputStream ( new BufferedInputStream( socket.getInputStream())); //サーバ側から送信された文字列を受信 byte[] buff = new byte[1024]; int a = is.read(buff); System.out.write(buff, 0, a); //ストリーム,ソケットをクローズ is.close(); socket.close(); }catch(Exception e){ System.out.println(e.getMessage()); e.printStackTrace(); } } }
サーバプログラム(Java) //Server.java import java.net.*; import java.lang.*; import java.io.*; public class Server{ public static void main( String[] args ){ try{ //ソケットを作成 ServerSocket svSocket = new ServerSocket(10000); //クライアントからのコネクション要求受付 Socket cliSocket = svSocket.accept(); //出力ストリームを作成 DataOutputStream os = new DataOutputStream( new BufferedOutputStream( cliSocket.getOutputStream())); //文字列を送信 String s = new String("Hello World!!\n"); byte[] b = s.getBytes(); os.write(b, 0, s.length()); //ストリーム,ソケットをクローズ os.close(); cliSocket.close(); svSocket.close(); }catch( Exception e ){ System.out.println(e.getMessage()); e.printStackTrace(); } } }
並列計算の枠組み (MPI) Massive parallel computer gateway Jobs Tasks user PC-Cluster
Initialization Communicator Acquiring number of process Acquiring rank Termination MPIの枠組み # include “mpi.h” int main( int argc, char **argv ) { MPI_Init(&argc, &argv ) ; MPI_Comm_size( …… ); MPI_Comm_rank( …… ) ; /* parallel procedure */ MPI_Finalize( ) ; return 0 ; }
通信方法 1対1通信 グループ通信 Process A Process B Receive/send data Receive/send data
1対1通信 [Sending] MPI_Send( void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) void *buf:Sending buffer starting address (IN) int count:Number of Data (IN) MPI_ Datatype datatype:data type (IN) int dest:receiving point (IN) int tag:message tag (IN) MPI_Comm comm:communicator(IN)
1対1通信 [Receiving] MPI_Recv( void *buf, int count, MPI_Datatypedatatype, int source, int tag, MPI_Commcomm, MPI_Statusstatus) void *buf:Receiving buffer starting address (OUT) int source:sending point (IN) int tag:Message tag (IN) MPI_Status *status:Status (OUT)
~Hello.c~ #include <stdio.h> #include "mpi.h" void main(int argc,char *argv[]) { int myid,procs,src,dest,tag=1000,count; char inmsg[10],outmsg[]="hello"; MPI_Status stat; MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD,&myid); count=sizeof(outmsg)/sizeof(char); if(myid == 0){ src = 1; dest = 1; MPI_Send(&outmsg,count,MPI_CHAR,dest,tag,MPI_COMM_WORLD); MPI_Recv(&inmsg,count,MPI_CHAR,src,tag,MPI_COMM_WORLD,&stat); printf("%s from rank %d\n",&inmsg,src); }else{ src = 0; dest = 0; MPI_Recv(&inmsg,count,MPI_CHAR,src,tag,MPI_COMM_WORLD,&stat); MPI_Send(&outmsg,count,MPI_CHAR,dest,tag,MPI_COMM_WORLD); printf("%s from rank %d\n",&inmsg,src); } MPI_Finalize(); }
1対1通信 MPI_Recv(&inmsg,count,MPI_CHAR,src, tag,MPI_COMM_WORLD,&stat); MPI_Send(&outmsg,count,MPI_CHAR,dest, tag,MPI_COMM_WORLD); MPI_Sendrecv(&outmsg,count,MPI_CHAR,dest, tag,&inmsg,count,MPI_CHAR,src, tag,MPI_COMM_WORLD,&stat);