マルチスレッド(2)

並列分散ソフトウェア

                                       電子・情報工学系
                                       新城 靖
                                       <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 では、 他に次のものがつかえる。

-XX:-UseLWPSynchronization
Many-to-Many thread based
default
Many-to-Many lwp based
-XX:+UseBoundThreads
One-to-One via bound threads
(sakura/Solaris7では使用不可) export LD_LIBRARY_PATH=/usr/lib/lwp
One-to-One via Alternate Libthread*
http://java.sun.com/docs/hotspot/threads/threads.html サンプルが次の場所にある。

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参照)。

◆バリア同期の例:弛緩法(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,新しい仕事);
	    }
	}
}

◆応用

◆ワークパイルコントローラ

workpile_t work_init(int max_pile, work_proc_t worker_proc, int n_threads)
初期化する。max_pile は、蓄える仕事の数の最大。worker_proc は、1回の仕事をするスレッド。n_threads は、スレッドの数。
void work_put(workpile_t wp, void *ptr)
仕事をワークパイルに加える。
void work_wait(workpile_t wp)
仕事がなくなるのを待つ。

◆並列クイックソート

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

■パイプライン

もともとのプログラムが専門家並列ならよい。 スレッドにはあまり適していない。

■性能

◆よい性能をえるために重要なこと

◆並列プログラムを書くためのガイドライン

◆gprofコマンド

アルゴリズムが時間を消費している所を知るための道具。

コンパイル時: -pg オプションを付ける。

実行すると gmon.out というファイルが作られる。 これを、実行形式ファイルと共に gprof コマンドに渡す。

◆spinロック

ロックの種類
sleeping (標準)
ロックが確保できない時、そのスレッドをキューに入れ、ブロック状態 にする。ロックを保持しているスレッドが、ロックを解放する時に起してもら う。
spin
ロックが確保できるまで、同期変数を繰り返し調べる。
スレッドをブロックさせたり起したりする操作は、重たい。 際どい領域が小さいなら、スピンした方が得。

ロックを確保したスレッドが、CPU を横取りされていたなら待っているのは無 駄になる。

無限のスピンは避けたい。 コンテキスト切り替えに要する時間の 50%-100% だけスピンするのがよい。 [Anderson 90]

■課題

次の課題から1つを選んで提出しなさい。問題を難しい方に変えてもよい。締 め切りは、2004/1/21 (水曜日) 18:00 とする。(23:59:59 ではない)。

レポートは、次のような形式の電子メールで送ること。

----------------------------------------------------------------------
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 を使ってもよいが、台数効果はうまく図れないかもしれない。 捕捉 を試して欲しい。

★配列の総和

配列が与えられた時に、次のような値を計算する並列プログラムを記述しなさ い。 注意:並列化しにくいものも混じっている。全部はやらなくてもよい。

★行列の掛け算を分割統治で

行列の掛け算をするプログラムを、分割統治法で書き直しなさい。部分行列に 分割して、掛け算して足す。配列の要素の並びに注意する。

★行列の掛け算をタスクバッグで

行列の掛け算をするプログラムを、タスクバッグ(ワークパイル)を使った手 法で書き直しなさい。ワーカは、CPU の数だけ作る。タスクは、CPU の数より も多くてもよい。

★その他

自分が持っている逐次プログラム、または、クラスタ計算用の並列プログラム を、Pthreads、または、Java を使って並列処理をするプログラムに書き換え なさい。そして、プロセッサ数を変えながら実行して、台数効果を調べなさい。
↑[もどる] ←[1月8日] ・[1月15日] →[1月22日]
Last updated: 2004/01/20 20:00:41
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>