並列プログラミングの practice 課題を解いてもらうための布教活動

33
並並並並並並並並並並 Practice 並並並並並並並並並並並並並並並並 並並

Upload: loan

Post on 22-Jan-2016

41 views

Category:

Documents


0 download

DESCRIPTION

並列プログラミングの Practice 課題を解いてもらうための布教活動. 田浦. 並列問題解決のステップ. decomposition ( 並列性抽出): 問題のタスクへの分割 mapping ( 負荷分散): タスクを API レベルのスレッド/プロセスにマッピング coordination: タスク間の通信,依存関係を API または instruction レベルの通信・同期に翻訳する. 最も簡単な例. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 並列プログラミングの Practice 課題を解いてもらうための布教活動

並列プログラミングのPractice

課題を解いてもらうための布教活動

田浦

Page 2: 並列プログラミングの Practice 課題を解いてもらうための布教活動

並列問題解決のステップ decomposition ( 並列性抽出 ):

• 問題のタスクへの分割 mapping ( 負荷分散 ):

• タスクを API レベルのスレッド / プロセスにマッピング

coordination:• タスク間の通信,依存関係を API または

instruction レベルの通信・同期に翻訳する

Page 3: 並列プログラミングの Practice 課題を解いてもらうための布教活動

最も簡単な例 for (i = 0; i < n; i++) {

a[i] = i * i * d;}s = 0;for (i = 0; i < n; i++) { s += a[i]; }

Page 4: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Decomposition

順序制約 ( 依存関係 ): • A B タスク A の終了後にタスク B を開始 関係のないものはどのような順番・タイミン

グで実行されるかわからない ( という前提で正しく動くように decomposition を行う )

a[0] = … a[1] = … a[2] = … a[n – 1] =…

s = 0; for (i = 0; i < n; i++) s += a[i];

Page 5: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Mapping

タスクを API レベルの並列性にマッピング• MPI :

• 並列性の源 : プロセス (mpirun –np P …)

• プロセス数は固定• Pthreads :

• 並列性の源 : スレッド (pthread_create)

• スレッド数は可変だが,多数作りすぎると性能ロスが大きい

• もちろんどの道 CPU は固定である

Page 6: 並列プログラミングの Practice 課題を解いてもらうための布教活動

本例題のタスク スレッドmapping

P 個のスレッド (t = 0, …, P – 1) スレッド t は i [nt / P, n(t + 1) / P) の更新

を行えばよい ( 等分 )

…スレッド 0スレッド 1スレッド 2 スレッド P – 1

スレッド 0

スレッド 0

Page 7: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Coordination 通信

• 実行するタスクが必要とするデータを送る ( 分散メモリ )

同期• 順序制約 ( 依存関係 ) を満たすための調停• i.e., 順序制約が満たされたタスクを実行

並行アクセスの制御• 順序制約のない複数のタスクによる,同一メモリロ

ケーションへのアクセスを調停 ( 共有メモリ )• 原子的な更新• 排他制御

Page 8: 並列プログラミングの Practice 課題を解いてもらうための布教活動

本例題における Coordination( 共有メモリ )

initially: run = done = 0; master() { /* thread 0 */

run = 1; work(0); atomic_increment_n_done(); while (n_done < P); calc_sum();}

worker(t) { /* thread t */ while (run == 0); work(t); atomic_increment_n_done(); }

Page 9: 並列プログラミングの Practice 課題を解いてもらうための布教活動

本例題における Coordination( 分散メモリ )

master() { /* processor 0 */ for p = 1, …, P – 1 send(p, run); work(0); n_done++; while (n_done < P) { received(done) => n_done++; } calc_sum();}

worker(t) { /* thread t */ receive(run()); work(t); send(master, done); }

Page 10: 並列プログラミングの Practice 課題を解いてもらうための布教活動

より一般的な場合 タスク間の仕事量がばらつく

• 負荷 != タスクの「数」 タスクの数や形が,プログラムを実行

しながら判明する• タスクの数 ? 負荷 ?

対処法 :• タスクを細かく分散する ( 大数の法則 )• 動的に mapping をする ( 動的負荷分散 )

Page 11: 並列プログラミングの Practice 課題を解いてもらうための布教活動

例 : Quicksort

sort(a, l, h) { … sort(a, c, h); sort(a, l, c);}

l c h

Page 12: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Qucksort の tasksort(0, 100)

sort(0, 37) sort(37, 100)

sort(0, 10) sort(10, 37) sort(37, 64) sort(64, 100)

… … … …

Page 13: 並列プログラミングの Practice 課題を解いてもらうための布教活動

例 2: fib

fib(n) { if (n < 2) return 1; else return fib(n – 1) + fib(n – 2);}

Page 14: 並列プログラミングの Practice 課題を解いてもらうための布教活動

fib の taskfib(5)

fib(4) fib(3)

fib(3) fib(2) fib(2) fib(1)

fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)

+ + +

+ +

+

Page 15: 並列プログラミングの Practice 課題を解いてもらうための布教活動

スレッド / プロセス タスクmapping の二つのスタイル

1 スレッド / プロセス 1 タスク ( 細粒度スレッド )• プログラムを単純に記述可能• スレッド / プロセス CPU の mapping は不確定

(OS そのほかに依存 ) 1CPU 1 スレッド (SPMD)

• タスク スレッド / プロセスの mapping を明示的に記述 ( プログラムが複雑 )

• タスク数 >> CPU 数のときは唯一の選択肢• プロセス数固定のモデル (e.g., MPI) でも唯一の選

択肢

Page 16: 並列プログラミングの Practice 課題を解いてもらうための布教活動

一般的な SPMD テンプレート タスクをあらわす構造体

• タスクの状態 : 実行可・不可 「実行可能」なタスクを保持する構造

体 (Runnable Queue, Task Queue, Scheduling Queue)

Task Queue

Page 17: 並列プログラミングの Practice 課題を解いてもらうための布教活動

一般的な SPMD テンプレートの動作

各スレッド (= プロセッサ ) の動作 while (!finishsed) {

t = get_task(); execute(t);}

task queue( 実行可能 task)

t

t t

execute新たに { 作られた・実行可能になった }task

Page 18: 並列プログラミングの Practice 課題を解いてもらうための布教活動

各スレッドの動作 execute(t) {

アプリ固有の動作 including … create_task: t’ = a new task created by executing t; mark t’ runnable (e.g., enqueue(t’)); … enable_task: t’ = task enabled by t’; mark t’ runnable (e.g., enqueue(t’));}

Page 19: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Task Queue の Design Choice

• Shared: 全体でひとつ.共有• Private: スレッドごとにひとつ

Page 20: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Shared Task Queue

自然に空いているプロセッサに task が実行される

ハードウェア共有メモリ以外では非現実的

ハードウェア共有メモリでも台数が多く,タスク粒度が小さいときはボトルネックになる

Page 21: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Private (per Thread) Task Queue

スレッド ( プロセッサ ) にひとつの task queue

スケーラブル 複雑化する問題 : 負荷分散

• Static• Dynamic

Page 22: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Private Task Queue + Static Load Balancing

全スレッドが offline に合意できる方法で taskがどの local task queue に入るかを決めておく• e.g., Quicksort : 木のノードの位置を符号化,それ

をハッシュする task 生成 : 適切なスレッドの queue に

enqueue 各スレッドは自分の local queue からのみ task

を取り出して実行 task が細かい粒度でスレッドに分配される

Page 23: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Private Task Queue + Dynamic Load Balancing

task 生成 : 任意の queue ( ほとんどの場合自分の private queue) に task を enqueue

何らかの方針で, private queue の間でtask を移動• PULL : 自分の private queue にタスクがな

い場合,他の (e.g., random) スレッドのqueue から task を奪う

• PUSH : 自分の private queue の task を時折他のスレッドに移す

Page 24: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Taxonomy

Shared

PrivateStatic L.B.

Dynamic L.B.Lazy (PULL)

Proactive (PUSH)

Page 25: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Lazy Task Creation

Private queue + dynamic L.B. + lazy (PULL) load distribution

Task queue は deque ( 両端から出し入れ可能な queue) ローカル

実行

負荷分散

Page 26: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Lazy Task Creation の動作 task 生成 先頭に push; 直ちに実行 task 終了 先頭から pop; 次を実行 task enabled 末尾に挿入 負荷分散 末尾の要素を移動

Page 27: 並列プログラミングの Practice 課題を解いてもらうための布教活動

Lazy Task Creation の効果

… … …

Page 28: 並列プログラミングの Practice 課題を解いてもらうための布教活動

まともな台数効果を得るための tips (1)

tips 以前の tips (Solaris のみ )• pthread_setconcurrency( 台数 )• thr_setconcurrency( 台数 )• いずれかを用いて実際の並列度 (利用し

たい CPU 数 ) を指定• 指定しないと 1 ( いくらスレッドを作って

も無駄 )

Page 29: 並列プログラミングの Practice 課題を解いてもらうための布教活動

まともな台数効果を得るための tips (2)

世の中はボトルネックだらけ• mutex lock は極力使わない

• compare & swap など, lock を用いない atomic update

• どうしても lock が必要なら, critical section を極力短く (< 数十命令 ) した上で spin lock

• 系 : libc default の malloc を使わない• もっとスケーラブルなライブラリを使う• http://www.yl.is.s.u-tokyo.ac.jp/gc/

• 系 : malloc を使ってそうなライブラリ (e.g., STL) を使わない

Page 30: 並列プログラミングの Practice 課題を解いてもらうための布教活動

すでに動的負荷分散機能を持つ言語

StackThreads/MP, MTCAMP• C/C++ のライブラリ , 拡張言語• http://www.yl.is.s.u-tokyo.ac.jp/mtcamp/• http://www.yl.is.s.u-tokyo.ac.jp/sthreads/

Cilk• C の拡張言語• http://supertech.lcs.mit.edu/cilk/

KLIC• 並列論理型言語• http://www.klic.org/

Page 31: 並列プログラミングの Practice 課題を解いてもらうための布教活動

MTCAMP

C の拡張情報理工の SunFire15K (istsun0) にイン

ストール済み (利用法は講義 HP に近日掲載 )

特徴 : 多数 (>> CPU 数 ) のスレッド生成を許容する

Page 32: 並列プログラミングの Practice 課題を解いてもらうための布教活動

構文 3 つの拡張 : mtc_sync, mtc_fork, --- mtc_sync {

… mtc_fork [shared( 変数名 ,…)] <文 >; … ---;}

Page 33: 並列プログラミングの Practice 課題を解いてもらうための布教活動

例 int fib(int n){ if (n < 2) return 1; else { int a, b; ST_POLLING(); mtc_sync { mtc_fork shared(a) a = fib(n - 1); b = fib(n - 2); ---; ST_POLLING(); return a + b; }}}