並列分散ソフトウェア
                                       電子・情報工学系
                                       新城 靖
                                       <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
	http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15
あるいは、次のページから手繰っていくこともできます。
	http://www.hlla.is.tsukuba.ac.jp/~yas/sie/
	http://www.is.tsukuba.ac.jp/~yas/index-j.html
	http://www.hlla.is.tsukuba.ac.jp/~yas/index-j.html
2004/01/20 19:40:05
Java から pthread_setconcurrency() を呼ぶためのクラスが次の場所にある。
~yshinjo/java/jni/NativeConcurrency/v9/
% cd ~yshinjo/java/jni/NativeConcurrency/v9% make run
env LD_LIBRARY_PATH=. java NativeConcurrencyTest NativeConcurrency.set( 3 ) returned 0 NativeConcurrency.get() returned 3 % cat NativeConcurrencyTest.java
// // NativeConcurrencyTest // 2004/01/07 20:20:28 class NativeConcurrencyTest { public static void main( String argv[] ) { int res ; res = NativeConcurrency.set( 3 ); System.out.println("NativeConcurrency.set( 3 ) returned "+res ); res = NativeConcurrency.get(); System.out.println("NativeConcurrency.get() returned "+res ); } } %
![]()
Java VM の JIT を止める(-Xint)と、うまく台数効果が測定できるかもしれない。
% java -Xint Filename![]()
Java レベルのスレッドと OS レベルのスレッドの対応関係を変更することも できる。Solaris 7 (sakura) で Java 1.4 を動かした場合、標準では、 Many-to-Many lwp based。次のように変更できる。Java 1.4 では、 他に次のものがつかえる。
sakura:~yshinjo/java/thread/SpinThreads/RunSpinThreads.java
[1] Steve Kleiman, Devang Shah and Bart Smaalders: "Programming with
Threads", Sun Microsystems Press, 1996.  ISBN 0-13-172389-8 
[2] Steve Kleiman, Devang Shah,Bart Smaalders著、岩本伸一訳: "実践マルチス
レッドプログラミング",アスキー出版局, 1998年.  ISBN 4-7561-1784-8
[3] Doug Lea: "Concurrent Programming in Java: Design Principles and
Patterns, Second edition", Addison-Wesley, November 1999.  (ISBN
0-201-31009-0). 
[4] ダグ リー (著), Doug Lea (原著), 松野良蔵 (翻訳): " "Javaスレッド
プログラミング―並列オブジェクト指向プログラミングの設計原理",翔泳社 
(2000).  ISBN: 4881359185
WWW上に追補がある。
http://gee.cs.oswego.edu/dl/cpj/
util.concurrent パッケージには、実用になるクラスが多数含まれている。
master()
{
	初期化;
	for( i=0 ; i<nthreads; i++ )
	{
	    pthread_create(,,slave,);
	}
	マスターの処理;/*必要なら*/
	for( i=0 ; i<nthreads; i++ )
	{
	    pthread_join(,,slave,);
	}
	終了処理;/*必要なら*/
}
slave(void *params)
{
	paramsからiを取り出す;
	仕事をする;
	結果を大域変数かparamsに返す;
	return; /* pthread_exit() */
}
% wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/ms_matrix-main.c % wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/ms_matrix.c % wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/Makefile % make ms_matrix-main gcc -D_REENTRANT ms_matrix-main.o -lpthread -lposix4 -o ms_matrix-main % ./ms_matrix-main 200 1 1 matrix_size==200, nthreads==1, niters==1, concurrenc==1 1.381 [sec] / 1 [iteration] == 1.381 [sec/iteration] 1 [iteration] / 1.381 [sec] == 0.724 [iteration/sec] % ./ms_matrix-main 200 1 1 matrix_size==200, nthreads==1, niters==1, concurrenc==1 1.391 [sec] / 1 [iteration] == 1.391 [sec/iteration] 1 [iteration] / 1.391 [sec] == 0.719 [iteration/sec] % ./ms_matrix-main 200 2 1 matrix_size==200, nthreads==2, niters==1, concurrenc==2 0.694 [sec] / 1 [iteration] == 0.694 [sec/iteration] 1 [iteration] / 0.694 [sec] == 1.441 [iteration/sec] % ./ms_matrix-main 200 3 1 matrix_size==200, nthreads==3, niters==1, concurrenc==3 0.494 [sec] / 1 [iteration] == 0.494 [sec/iteration] 1 [iteration] / 0.494 [sec] == 2.025 [iteration/sec] % ./ms_matrix-main 200 4 1 matrix_size==200, nthreads==4, niters==1, concurrenc==6 0.382 [sec] / 1 [iteration] == 0.382 [sec/iteration] 1 [iteration] / 0.382 [sec] == 2.621 [iteration/sec] % ./ms_matrix-main 200 5 1 matrix_size==200, nthreads==5, niters==1, concurrenc==6 0.333 [sec] / 1 [iteration] == 0.333 [sec/iteration] 1 [iteration] / 0.333 [sec] == 3.005 [iteration/sec] % ./ms_matrix-main 200 6 1 matrix_size==200, nthreads==6, niters==1, concurrenc==6 0.279 [sec] / 1 [iteration] == 0.279 [sec/iteration] 1 [iteration] / 0.279 [sec] == 3.587 [iteration/sec] %台数効果をうまく図る方法
master()
{
	初期化;
	for( i=0 ; i<nthreads; i++ )
	{
	    pthread_create(,,slave,);
	}
	while( !termcond )
	{
	    マスターの処理A;/*必要なら*/
	    barrier_wait();
	    マスターの処理B;/*必要なら*/
	    barrier_wait();
	}
	for( i=0 ; i<nthreads; i++ )
	{
	    pthread_join(,,slave,);
	}
	終了処理;/*必要なら*/
}
slave(void *params)
{
	paramsからiを取り出す;
	while( !termcond )
	{
	    /* マスターの処理Aの完了を待つ */
	    barrier_wait();
	    スレーブ処理B;
	    結果を大域変数かparamsに返す;
	    barrier_wait();
	}
	return; /* pthread_exit() */
}
ループの間、マスタの仕事がないこともある。その場合は、マスタはバリアに
は参加しない(relax.c参照)。
wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/ms_relax.c wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/ms_relax-main.c wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/barrier.c wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/Makefile make ms_relax-main.c ./ms_relax-main
worker_thraed()
{
	while( (ptr=work_get(workpile))!=NULL )
	{
	    ptrが示す仕事をする;
	    if( 新しい仕事ができた )
	    {
		work_put(workpile,新しい仕事);
	    }
	}
}
wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/quicksort-main.c wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/quicksort.c wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/workpile.c wget http://www.hlla.is.tsukuba.ac.jp/~yas/sie/pdsoft-2003/2004-01-15/ex/Makefile make quicksort-main ./quicksort-main
コンパイル時: -pg オプションを付ける。
実行すると gmon.out というファイルが作られる。 これを、実行形式ファイルと共に gprof コマンドに渡す。
ロックの種類ロックを確保したスレッドが、CPU を横取りされていたなら待っているのは無 駄になる。
無限のスピンは避けたい。 コンテキスト切り替えに要する時間の 50%-100% だけスピンするのがよい。 [Anderson 90]
レポートは、次のような形式の電子メールで送ること。
---------------------------------------------------------------------- To: yas@is.tsukuba.ac.jp Subject: [pdsoft/report-thread-2] <内容に関したサブジェクト> 学籍番号 200354321 (各自の学籍番号で置き換える) 名前 漢字の名前 <本文> ----------------------------------------------------------------------注意:sakura の新城のログイン名は、yshinjo である。 レポートは、yas@is.tsukuba.ac.jp に送ること。 Subject: には、pdsoft という文字とレポートの番号(report-thread-2)を必 ず含めなさい。
電子メールの本文の先頭に学籍番号と名前(漢字の名前がある人は、漢字で) を書きなさい。
内容は、文法的に正しい、日本語、または英語で書くこと。文章には、述語を 付ける。体言止めは、使ってはいけない。単にプログラムを含めるのではなく、 「以下に○○のプログラムを示す」と書く。実行結果を必ず付ける。
送られたレポートには、最初の締切り以降にまとめて確認応答(acknowledge) を返す。メッセージの紛失、クラッシュ等に対応するために、時間切れによる 再送などのリカバリは適宜やること。
送ったレポートは、講義が終るまで保存しなさい。
台数効果を調べること。すなわち、スレッド/CPUの数が増えた時に、実行時間 やスループットどうなるかを調べて報告しなさい。台数効果が報告されていな いものは、再提出にする。必ずしもよい結果が出る必要はないが、悪い結果が 出た時には、どこに原因があるかを考察しなさい。
マスタ・スレーブや タスクバッグ(ワークパイル) でプログラムを書くこと。 その場合、pthread_mutex_lock() も pthread_cond_wait() も出てこない。バ リア同期を使ってもよいが今日の課題では使わなくても可能である。
Java を使ってもよいが、台数効果はうまく図れないかもしれない。 捕捉 を試して欲しい。
配列が与えられた時に、次のような値を計算する並列プログラムを記述しなさ い。