Book Chapter 8

49
Concurrency: message passing 1 ©Magee/ Kramer 第 11 第 第第第第第第第第第

Transcript of Book Chapter 8

Page 1: Book Chapter 8

Concurrency: message passing 1©Magee/Kramer

第 11 章

並行アーキテクチャ

Page 2: Book Chapter 8

Concurrency: message passing 2©Magee/Kramer

並行アーキテクチャ

概念 : アーキテクチャ: 並行システムにおけるプロセスが作る構造

モデル : Filter Pipeline Supervisor Worker Announcer-Listener

実践 :

Page 3: Book Chapter 8

Concurrency: message passing 3©Magee/Kramer

ソフトウェア・アーキテクチャとは

アーキテクチャとは建築物,建築学基本設計思想

コンピュータ関連コンピュータ・アーキテクチャ

狭義には命令セットネットワーク・アーキテクチャ

ISO/OSI の階層モデル

3

Page 4: Book Chapter 8

Concurrency: message passing 4©Magee/Kramer

アーキテクチャの役割

システム全体の構造を定めるもの部品合成としてのシステム組織大域的制御構造通信プロトコルデータベースとデータアクセス物理的分散配置処理規模と性能将来の発展方向の見通し

4

Page 5: Book Chapter 8

Concurrency: message passing 5©Magee/Kramer

ソフトウェア・アーキテクチャとは ( 続き )

計算部品とそれらの相互作用という形でシステムを記述するもの

システム要求と構築されるシステムの要素との対応をつけ,設計判断に根拠を与える.

システム レベルの性質として,容量,スループット,・整合性,部品の適合性などを考慮.

設計は,合成の規則と振舞いの規則を定める.

5

Page 6: Book Chapter 8

Concurrency: message passing 6©Magee/Kramer

建築様式 (Architecture Style)

スタイル ( 様式 ) の例データフロー

バッチ列パイプとフィルタ

呼び出し 復帰システム・メインとサブルーチンOO システム層別

6

Page 7: Book Chapter 8

パイプとフィルターアーキテクチャ

層別アーキテクチャ

黒板アーキテクチャ

7

Page 8: Book Chapter 8

Concurrency: message passing 8©Magee/Kramer

建築様式(2)

独立部品通信プロセス事象システム

バーチャルマシンインタープリタルールベース・システム

データ中心システムデータベースハイパーテキスト黒板システム

8

Page 9: Book Chapter 8

Concurrency: message passing 9©Magee/Kramer

アーキテクチャ記述言語 (ADL)

アーキテクチャの構造を記述するための言語構成要素:

部品 (component) 結合子 (connector)

ADL の例Wright (CMU)Darwin (Imperial College)RAPIDE (Stanford U.)GEN-VOCA (U. Texas)

Page 10: Book Chapter 8

Concurrency: message passing 10©Magee/Kramer

アーキテクチャに関連する概念

フレームワーク特定の領域向けにアーキテクチャを具体化した骨組み

例:金融商品販売管理システム用フレームワークWeb アプリケーション用フレームワーク

Struts, Ruby on Rails, JBoss

特殊化すべき部分して実装「高温部 (hotspot) 」のみ継承などで追加

10

Page 11: Book Chapter 8

Concurrency: message passing 11©Magee/Kramer

アーキテクチャに関連する概念 (2)

設計パターン設計上繰り返し現れる有用なパターンアーキテクチャより小さい単位建築家 C. Alexander の「パターン言語」の影響例 : G4 による 23 の設計パターン

Observer, Mediator, Visitor, Proxy など

11

Page 12: Book Chapter 8

Concurrency: message passing 12©Magee/Kramer

11.1 フィルタのパイプライン

フィルタ: ここでは 1 入力ストリームを 1 出力ストリームに変換 するプロセス(一般には多入力,多出力)

パイプライン: フィルタをつなげて作る構造

Page 13: Book Chapter 8

Concurrency: message passing 13©Magee/Kramer

エラトステネスのふるいによる素数生成

234567 ... n

=>23*5*7 ... n

Figure 11.1 Primes Sieve process architecture.

Page 14: Book Chapter 8

Concurrency: message passing 14©Magee/Kramer

モデル

canst MAX = 9range NUM =2..MAXset S ={[NUM],eos}PIPE = (put[x:S]->get[x]->PIPE).

GEN = GEN[2],GEN[x:NUM] = (out.put[x] -> if x<MAX then GEN[x+1] else (out.put.eos -> end ->GEN) ).

PIPE はアーキテクチャの要素としてはコンポーネントをつなぐ結合子 (connector) の役割を果たす.

Page 15: Book Chapter 8

Concurrency: message passing 15©Magee/Kramer

Filter

FILTER = (in.get[p:NUM]->prime[p]->FILTER[P] |in.get.eos->ENDFILTER ),FILTER[p:NUM] = (in.get[x:NUM] -> if x%p!=O then (out.put[x]->FILTER[p]) else FILTER[P] |in.get.eos->ENDFILTER ),ENDFILTER = (out.put.eos->end->FILTER).

Page 16: Book Chapter 8

Concurrency: message passing 16©Magee/Kramer

Primes

||PRIMES(N=4) = ( gen:GEN ||pipe[O..N-1]:PIPE ||filter[O..N-1]:FILTER )/{pipe[O]/gen.out, pipe[i:O..N-1]/filter[i].in, pipe[i:1..N-1]/filter[i-1].out, end/{filter[O..N-1].end,gen.end} }@{filter[O..N-1].prime,end}.

Page 17: Book Chapter 8

Concurrency: message passing 17©Magee/Kramer

Unbuffered Pipes

||PRIMESUNBUF(N=4) = (gen:GEN || filter[O..N-1]:FILTER) /{pipe[O]/gen.out.put, pipe[i:O..N-1]/filter[i].in.get, pipe[i:1..N-1]/filter[i-1].out.put, end/{filter[O..N-1].end,gen.end} }@{filter[O..N-1].prime,end}.

Page 18: Book Chapter 8

Concurrency: message passing 18©Magee/Kramer

Abstracting from Application Detail

||AGEN = GEN/{out.put/out.put[NUM)}. ||AFILTER = FILTER/{out.put/out.put[NUM], in.get/in.get.[NUM], prime/prime[NUM] }.||APIPE = PIPE/{put/put[NUM],get/get[NUM]}.

Page 19: Book Chapter 8

Concurrency: message passing 19©Magee/Kramer

Multi-Slot Pipes

||MPIPE(B=4) = if B==1 then APIPE else (APIPE/{mid/get} || MPIPE(B-1)/{mid/put}) @{put,get}.

||APRIMES(N=4,B=3) = (gen:AGEN || PRIMEP(N) || pipe[O..N-1]:MPIPE(B) || filter[O..N-1]:AFILTER) /{pipe[O]/gen.out, pipe[i:O..N-1]/filter[i].in, pipe[i:1..N-1]/filter[i-1].out, end/{filter[O..N-1].end,gen.end} }.

Page 20: Book Chapter 8

Concurrency: message passing 20©Magee/Kramer

Architectural Property Analysis

progress END = {end}

propertyPRIMEP(N=4) = PRIMEP[0],PRIMEP[i:0..N] = (when (i<N) filter[i].prime->PRIMEP[i+1] |end -> PRIMEP ).

Page 21: Book Chapter 8

Concurrency: message passing 21©Magee/Kramer

Primes Sieve Implementation

Page 22: Book Chapter 8

Concurrency: message passing 22©Magee/Kramer

Primes class diagram

Page 23: Book Chapter 8

Concurrency: message passing 23©Magee/Kramer

Java による実装

class PrimesCanvas extends Canvas {

// display val in an upper box numbered index// boxes are numbered from the leftsynchronized void print(int index, int val){...}

// display val in a lower box numbered index// the lower box indexed by 0 is not displayedsynchronized void prime(int index, int val){...}

// clear all boxessynchronized void clear{) {...}}

Page 24: Book Chapter 8

Concurrency: message passing 24©Magee/Kramer

Java による実装

class Generator extends Thread { private PrimesCanvas display; private Pipe<Integer> out; static int MAX = 50; Generator(Pipe<Integer> c, PrimesCanvas d) {out=c; display = d;} public void run() { try { for (int i=2;i<=MAX;++i) { display.print(0,i); out.put(i); sleep(500);} display.print(0,Primes.EOS); out.put(Primes.EOS); } catch (InterruptedException e){} }}

Page 25: Book Chapter 8

Concurrency: message passing 25©Magee/Kramer

Java による実装

class Filter extends Thread { private PrimesCanvas display; private Pipe<Integer> in,out; private int index; Filter(Pipe<Integer> i, Pipe<Integer> o, int id, PrimesCanvas d) {in = i; out = o; display = d; index = id;} public void run() { int i,p; try { p = in.get(); display.prime(index, p); if (p==Primes.EOS && out!=null) { out.put(p); return;} while(true) { i= in.get(); display.print(index,i); sleep(1000); if (i==Primes.EOS) { if (out!=null) out.put(i); break; } else if (i%p!=0 && out!=null) out.put(i);} } catch (InterruptedException e){} }}

Page 26: Book Chapter 8

Concurrency: message passing 26©Magee/Kramer

Java による実装

public interface Pipe<T> { public void put(T o) throws InterruptedException; public T get() throws InterruptedException}

// Buffered pipe implementationpublic class PipeImplBuf<T> implements Pipe<T> { Buffer<T> buf = new BufferImpl<T>(10); public void put(T o) throws InterruptedException { buf.put(o);} public T get() throws InterruptedException { return buf.get();}}

Page 27: Book Chapter 8

Concurrency: message passing 27©Magee/Kramer

Why Use Buffering?

効率のためthread context switching を減らす

Page 28: Book Chapter 8

Concurrency: message passing 28©Magee/Kramer

11.2 Supervisor-Worker

Page 29: Book Chapter 8

Concurrency: message passing 29©Magee/Kramer

Linda Tuple Space

Data tuple in a tuple space has the form:("tag", value1,...,valuen)

Basic operations:out("tag", exprl,...,exprn) //input the matched tuple and remove it in("tag", field1,...,fieldn) //same as in except not removingrd("tag", field1,...,fieldn)inp, rdp //non-blocking version of in and rd, //return true when matching is found

Page 30: Book Chapter 8

Concurrency: message passing 30©Magee/Kramer

Tuple Space Model

const N = ...set Tuples = {...}const False = 0const True = 1range Bool = False..TrueTUPLE(T=‘any) = TUPLE[0],TUPLE[i:0..N] = (out[T] -> TUPLE[i+1] |when (i>0) in[T] -> TUPLE[i-1] |when (i>0) inp[True][T] -> TUPLE[i-1] |when (i==0) inp[False][T] -> TUPLE[i] |when (i>0) rd[T] -> TUPLE[i] |rdp[i>0][T] -> TUPLE[i] ).||TUPLESPACE = forall [t:Tuples] TUPLE(t).

Page 31: Book Chapter 8

Concurrency: message passing 31©Magee/Kramer

LTS for TUPLE value any with N=2

Page 32: Book Chapter 8

Concurrency: message passing 32©Magee/Kramer

Tuple Space Implementationpublic interface TupleSpace { // deposits data in tuple space public void out(String tag, Object data); // extracts object with tag from tuple space, // blocks if not available public Object in(String tag) throws InterruptedException; // reads object with tag from tuple space, // blocks if not available public Object rd(String tag) throws InterruptedException; // extracts object if available, // return null if not available public Object inp(String tag); //reads object if available, return null if not available public Object rdp(String tag);}

Page 33: Book Chapter 8

Concurrency: message passing 33©Magee/Kramer

public class Entry extends Port { private CallMsg cm; 

public Object call(Object req) throws InterruptedException { Channel clientChan = new Channel(); send(new CallMsg(req,clientChan)); return clientChan.receive(); } 

public Object accept()throws InterruptedException { cm = (CallMsg) receive(); return cm.request; } 

public void reply(Object res) throws InterruptedException { cm.replychan.send(res); } 

private class CallMsg { Object request; Channel replychan; CallMsg(Object m, Channel c) {request=m; replychan=c;} }}

Supervisor-Worker Model

アルゴリズムのスケッチSupervisor:: forall tasks: out("task",...) forall results: in("result",...) out("stop")Worker:: while not rdp("stop") do in("task",...) compute result out("result",...)

const N = 2set Tuples = {task,result,stop}set TupleAlpha={{in,out,rd,rdp[Bool],inp[Bool]}.Tuples}

Page 34: Book Chapter 8

Concurrency: message passing 34©Magee/Kramer

public class Entry extends Port { private CallMsg cm; 

public Object call(Object req) throws InterruptedException { Channel clientChan = new Channel(); send(new CallMsg(req,clientChan)); return clientChan.receive(); } 

public Object accept()throws InterruptedException { cm = (CallMsg) receive(); return cm.request; } 

public void reply(Object res) throws InterruptedException { cm.replychan.send(res); } 

private class CallMsg { Object request; Channel replychan; CallMsg(Object m, Channel c) {request=m; replychan=c;} }}

Supervisor-Worker Model

SUPERVISOR = TASK[1],TASK[i:1..N] = (out.task -> if i<N then TASK[i+1] else RESULT[1]),RESULT[i:1..N] = (in.result -> if i<N then RESULT[i+1] else FINISH),FINISH = (out.stop -> end -> STOP) + TupleAlpha.

WORKER = (rdp[b:Bool].stop-> if (!b) then (in.task -> out.result -> WORKER) else (end -> STOP) )+TupleAlpha.

Page 35: Book Chapter 8

Concurrency: message passing 35©Magee/Kramer

public class Entry extends Port { private CallMsg cm; 

public Object call(Object req) throws InterruptedException { Channel clientChan = new Channel(); send(new CallMsg(req,clientChan)); return clientChan.receive(); } 

public Object accept()throws InterruptedException { cm = (CallMsg) receive(); return cm.request; } 

public void reply(Object res) throws InterruptedException { cm.replychan.send(res); } 

private class CallMsg { Object request; Channel replychan; CallMsg(Object m, Channel c) {request=m; replychan=c;} }}

Supervisor-Worker Model

ATEND = (end->ENDED),ENDED = (ended->ENDED).

||SUPERVISOR_WORKER = (supervisor:SUPERVISOR || {redWork,blueWork}:WORKER || {supervisor,redWork,blueWork}::TUPLESPACE || ATEND )/{end/{supervisor,redWork,blueWork}.end}.

Page 36: Book Chapter 8

Concurrency: message passing 36©Magee/Kramer

Analysis

Safety analysis reveals the following deadlock:

Trace to DEADLOCK:supervisor.out.tasksupervisor.out.taskredWork.rdp.0.stop - rdp returns falseredWork.in.taskredWork.out.resultsupervisor.in.resultredWork.rdp.0.stop - rdp returns falseredWork.in.taskredWork.out.resultsupervisor.in.resultredWork.rdp.0.stop - rdp returns falsesupervisor.out.stopblueWork.rdp.1.stop - rdp returns true

Page 37: Book Chapter 8

Concurrency: message passing 37©Magee/Kramer

Revised Algorithms

Supervisor:: forall tasks: out("task",...) forall results: in("result",...) out("task",stop)Worker:: while true do in("task",...) if value is stop then out("task",stop); exit compute result out("result",...)

Page 38: Book Chapter 8

Concurrency: message passing 38©Magee/Kramer

Revised Model

set Tuples = {task,task.stop,result}SUPERVISOR = TASK[1],TASK[i:1..N] = (out.task -> if i<N then TASK[i+1] else RESULT[1]),RESULT[i:1..N] = (in.result -> if i<N then RESULT[i+1] else FINISH),FINISH = (out.task.stop -> end -> STOP) + TupleAlpha.WORKER = (in.task -> out.result -> WORKER |in.task.stop -> out.task.stop -> end ->STOP ) + TupleAlpha.

Page 39: Book Chapter 8

Concurrency: message passing 39©Magee/Kramer

Supervisor-Worker Implementation

Page 40: Book Chapter 8

Concurrency: message passing 40©Magee/Kramer

Program

class SupervisorCanvas extends Canvas { // display rectangle slice i with color c, add a to area field synchronized void setSlice( int i,double a,Color c) {...} // reset display to clear rectangle slices and draw curve for f synchronized void reset (Function f) {...}}class WorkerCanvas extends Panel { // display current task number val synchronized void setTask(int val) {...);}interface Function { double fn(double x);}

Page 41: Book Chapter 8

Concurrency: message passing 41©Magee/Kramer

Speedup and Efficiencyspeedup: time of sequential program / time of parallel

programefficiency: speedup / no. of processors

e.g. 12 seconds by sequential program, 4 seconds by parallel program with 6 processors => speedup: 3, efficiency: 0.5 (50%)

The integral example will not speed up, because tasks by workers take very small amount of time.

The Supervisor-Worker architecture is successfully applied to the problem like image rendering using ray-tracing techniques.

Page 42: Book Chapter 8

Concurrency: message passing 42©Magee/Kramer

Announcer-Listener

Page 43: Book Chapter 8

Concurrency: message passing 43©Magee/Kramer

Announcer-Listener Model (Event Manager)

set Listeners = {a,b,c,d}set Pattern = {pat1,pat2}REGISTER =IDLE,IDLE = (register[p:Pattern] -> MATCH[p] |announce[Pattern] -> IDLE ),MATCH[p:Pattern] = (announce[a:Pattern] -> if (a==p) then (event[a] -> MATCH[p] |deregister -> IDLE) else MATCH[p] |deregister -> IDLE).||EVENTMANAGER = (Listeners:REGISTER) /{announce/Listeners.announce}.

Page 44: Book Chapter 8

Concurrency: message passing 44©Magee/Kramer

LTS for a:REGISTER

Page 45: Book Chapter 8

Concurrency: message passing 45©Magee/Kramer

Announcer-Listener Model (Announcer, Listener)

ANNOUNCER = (announce[Pattern] -> ANNOUNCER).LISTENER(P='pattern) = (register[P] -> LISTENING),LISTENING = (compute -> LISTENING |event[P] -> LISTENING |event[P] -> deregister -> STOP )+{register[Pattern]}.||ANNOUNCER_LISTENER = ( a:LISTENER('pat1) ||b:LISTENER('pat2) ||c:LISTENER('pat1) ||d:LISTENER('pat2) ||EVENTMANAGER ||ANNOUNCER ||Listeners:SAFE).

Page 46: Book Chapter 8

Concurrency: message passing 46©Magee/Kramer

Analysis

property SAFE = (register[p:Pattern] -> SAFE[p]), SAFE[p:Pattern] = (event[p] -> SAFE[p] |deregister -> SAFE ).

progress ANNOUNCE[p:Pattern] = {announce[p]}

Page 47: Book Chapter 8

Concurrency: message passing 47©Magee/Kramer

Announcer - Listener Implementation

Page 48: Book Chapter 8

Concurrency: message passing 48©Magee/Kramer

BoxCanvas class

class BoxCanvas extends Canvas { // clear all boxes synchronized void reset() {...} // draw colored box id at position x,y synchronized void moveBox(int id, int x, int y) {...} // draw black box id at position x,y synchronized void blackBox(int id, int x, int y) {...}}class BoxMover extends Thread {... synchronized void isHit(int mx, int my) { hit = (mx>x && mx<x+display.BOXSIZE && my>y && my<y+display.BOXSIZE); if (hit) notify();} ... class MyListener extends MouseAdapter { public void mousePressed(MouseEvent e) { isHit(e.getX(),e.getY());}}

Page 49: Book Chapter 8

Concurrency: message passing 49©Magee/Kramer

レポート

3 章から 10 章にある課題を解くこと 少なくとも 3題を解いて,それをレポートとして提出する.

締切: 2月 5日 ( 金) 17:00 提出方法: 玉井に直接提出するか学内便で送付 1 階事務の長森さんに出してもよい