並列・分散プログラムの
状態遷移モデル
講義全体の思想と目標
並列・分散プログラムの実行を定式化する
定式化により
• 並列・分散アルゴリズムの正しさを正確に述べる
• 並列・分散アルゴリズムの正しさを証明する
• ある問題の不可能性(条件を満たすアルゴリズム
が存在しないこと)を証明する
並列・分散プログラミングモデル
メッセージパッシング
• プロセス + send/receiveによる通信・協調
共有メモリ
• プロセス + 共有メモリ(read/write)による通信・協調
もっと高水準なモデルも存在するが,講義で
は主に低水準なモデルを対象とする
• 低水準ゆえ汎用的
• 現実に多く使われている(pthread, MPI, etc.)
• 高水準なモデルの実装に必要
動機付け:並列プログラムの難しさ
以下は皆,似ていることの言い換え
• 「大域的な状態」を観測できない
• 出来事に大域的な「順序」が存在しない
• 操作の不可分性・原子性が保証できない
ほとんどの場合動作が非決定的である
簡単でないこと
• 複数の場所の変数を「一度に」観測する
• 複数の場所の変数を「一度に」更新する
例:変数の同時更新
プロセスAとB: ともに(ローカル)変数pを保持
• 初期値は一致しているとする
目的:
• プロセスA : 何回かpをともに0にセット
• プロセスB : 何回かpをともに1にセット
• 回数・タイミングは不明
• 実行された操作のうち,どの値が残っても良いが,
両者が食い違うのは×(“同時”更新)
最初の試み
A:
while (1) {
… p = 0; send(B, update);
| received(update) p = 1;
}
B:
while (1) {
… p = 1; send(A, update);
| received(update) p = 0;
}
“p=0”
“q=0”
p=0
p=1
p=?
“p=1”
“p=1”
p=1
p=0
p=?
教訓
二つのプロセッサの変数を両方同時に更新
するのは自明でない
複数の更新が「インターリーブ」する可能性が
ある
原子性(不可分性)の欠如
第2回目の試み: 更新中フラグの導入
アイデア:
• 自分が更新中(locked)の間は相手の更新を待たせ
る
• 自分の更新が終了後,相手の更新を実行する
locked = 1
更新中フラグ
A: (me = 0, him = 1; Bは逆)
req = 0;
/* 相手からの未処理リクエスト */
locked = 0; /* 自分が相手にリクエスト中 */
while (1) {
!locked && …
p = me; send(him, update); locked = 1;
| received(update) req = 1;
| req && !locked p = him; req = 0; send(him, ok);
| received(ok) locked = 0;
}
正しい終了状態: pが一致.req/lockedはともに0
一見正しそう?
Aがひとたびsend(update) を実行したら,okを
受け取るまで,p = 1を実行しない
okを受け取るには,Bでp = 0が実行されてい
るはず
Bがその後p = 1を実行するかもしれないが,
その場合は自分もokの後にupdateを受け取
るはず(同一の送信者受信者間でのメッセー
ジ順序の保存を仮定)
誤り
p=?
p=0
l=0
l=1
r=0
r=1
“p=0”
“q=0”
“p=1”
“p=1”
p=?
p=1
l=0
l=1
r=0
r=1
デッドロック
A: (me = 0, him = 1; Bは逆)
req = 0;
/* 相手からの未処理リクエスト */
locked = 0; /* 自分が相手にリクエスト中 */
while (1) {
!locked && …
p = me; send(him, update); locked = 1;
| received(update) req = 1;
| req && !locked p = him; req = 0; send(him, ok);
| received(ok) locked = 0;
}
教訓
分散システムの終了状態
• これ以上実行可能な文がなくなること
• プログラムの文面上の終了
望ましい状態に,いつか実際に到達すること
を証明する必要がある
• デッドロック: 間違った状態で終了する実行
• ライブロック: 望ましい状態に達しないまま,終了
しない(無限の長さを持つ)実行
この例題の一般化
複数プロセスにまたがるデータの原子的な更新
• データベースの更新 (直列化可能性)
分散共有メモリ
• 複製を伴うデータの一貫性のある更新(逐次一貫性)
Atomicマルチキャスト
• 全員に同じ順序でメッセージが届くマルチキャスト
注
問題は分散メモリのせいではない.共有メモ
リでも,複数の変数の更新には同じ困難があ
る
A : pA = 0; pB = 0;
B: pB = 1; pA = 1;
ABBA
並列・分散計算のモデル
構成要素
• プログラム(プロセス)の記法
• プログラム 1プロセスの状態遷移グラフ
• 多数のプロセスの状態遷移グラフ + 通信手段
大域的な状態遷移グラフ
メッセージパッシングプロセス
定義:メッセージパッシングプロセスとは5つ組
Z , I, i, s, r
• Z : プロセスの状態の集合
• I : 初期状態の集合( Z)
• i : プロセス内状態遷移関係の集合( Z Z)
• 記法: z i z’
• s : 送信による状態遷移関係の集合( Z M Z)
• 記法: z s(m) z’
• r : 受信による状態遷移関係の集合( Z M Z)
• 記法: z r(m) z’
• ただしz, z’ Z, m M : メッセージの集合
非同期メッセージパッシングシステム
nプロセス + 送受信システムC, I,
大域状態 C = z1, z2, … , zn, M
• M : メッセージのマルチ集合 = 送られて,まだ受け取
られていないメッセージの集合
• 変種
• Mを受信プロセスごとにわける(M1, … , Mn)
• Mを送信,受信プロセスペアごとに分ける(M11 , … , Mnn)
• 同一プロセスペア間でのメッセージ順序の保存(FIFO性)
大域初期状態 I = I1 … In
非同期メッセージパッシングシステム
の大域状態遷移
プロセスiの内部遷移
• z1, … , zi, … , zn, M z1, … , zi’, … , zn, M
iff zi i zi’
プロセスiの送信による遷移
• z1, … , zi, … , zn, M z1, … , zi’, … , zn, M {m}
iff zi s(m) zi’
プロセスiの受信による遷移
• z1, … , zi, … , zn, M {m} z1, … , zi’, … , zn, M
iff zi r(m) zi’
非同期メッセージパッシングシステム
の実行
c 1 c2 …
• ci : 大域状態( C)
• ci ci+1 : 先で定義した大域状態遷移
メッセージパッシングプログラムの記
述法(1)
通常の手続き的な記述+通信・同期文
通信・同期文
• 送信:
send(dest, tag(式, 式, …))
• ガード付き文:
条件式 行動
| 条件式 行動
|…
| 条件式 行動
条件式:
• received(tag(a, b, …))または 局所変数からなる式
メッセージパッシングプログラムの記述法
(2)
本質的ではないが,しばしば以下の条件を設
ける(条件式 行動をひとつの状態遷移
とみなせる):
• 条件式は副作用なしの式
• 行動部で実行されるsendは高々1つ
• 条件式部がreceivedの場合, 行動部で
はsendは実行されない
プログラムと状態遷移系の関係
プロセスの状態 = 変数の値 + 実行場所(プロ
グラムカウンタ etc.)
状態遷移
• 送受信以外の一連の文の実行:内部遷移
• 一回のsend文の実行を含む一連の文
• z s(m) z’ (z, z’は一連の文の実行前・後の状態)
• received(m) 送受信を含まない一連の文
• z r(m) z’ (同上)
注:
いわゆるnon-blocking受信
• received(m) …
| true …
このモデルは,いわゆるnon-blocking送信(送
信チャネルのバッファ容量は無限大)
重要な制約
ひとつの状態遷移でおこることは以下のひとつ(原
子性の欠如)
• 一プロセスpの内部状態変化
• 一プロセスpの内部状態変化+ pによる一メッセージの送
信
• 一プロセスの内部状態変化+ pによる一メッセージの受信
• おのおのをpによる遷移と呼ぶ
複数の状態遷移が可能な状態では,次にどの遷移
が起こるかは非決定的
共有メモリシステムのモデル
定義:共有メモリプロセスとは5つ組
Z , I, i, w, r
• Z : プロセスの状態の集合
• I : 初期状態の集合( Z)
• i : プロセス内状態遷移関係の集合( Z Z)
• 記法: z i z’
• w : 共有変数への書き込みによる状態遷移関係の集合( Z A
M Z)
• 記法: z w(a, m) z’
• r : 共有変数からの読み込みによる状態遷移関係の集合( Z A
M Z)
• 記法: z r(a, m) z’
• ただしA : 共有変数(アドレス)の集合,M : メッセージの集合
共有メモリシステム
nプロセス + 共有変数の集合
大域状態 C = z1, z2, … , zn, M
• M : 共有変数(A M )
大域初期状態 I = I1 … In
共有メモリシステムの大域状態遷移
プロセスiの内部遷移
• z1, … , zi, … , zn, M z1, … , zi’, … , zn, M
iff zi i zi’
プロセスiのwriteによる遷移
• z1, … , zi, … , zn, G z1, … , zi’, … , zn, G[a:=m]
iff zi w(a, m) zi’
プロセスiのreadによる遷移
• z1, … , zi, … , zn, G z1, … , zi’, … , zn, G
iff zi r(a, m) zi’ かつ G(a) = m
共有メモリプログラムの記述法
通常の手続き的な記述+共有変数アクセス
共有変数アクセス
• 書き込み:
a := v (a は共有変数)
• ガード付き文:
条件式 文
| 条件式 文
|…
| 条件式 文
制約: 条件式と対応する文には共有変数が高々1つしか現
れない
プログラムの正しさ
多くの場合,プログラムから導かれる状態遷
移系に関して,以下の二つを示すことになる
• 正しい終了: 初期状態から到達可能な終了状態
(これ以上の遷移がない状態)で,常にある望まし
い性質が成り立っている
• 停止性: 初期状態から,常に有限回の状態遷移
で終了状態に達する(停止性)
正しい終了
多くの場合,系のある「不変条件」Pを,以下
のように証明することに帰着
• P(i) for each i I (初期状態でPが成立)
• P(c) かつ c c’ ならばP(c’)
Pを証明した後で
• P(c)かつcが終了状態 Q(c)
• Q(c)が示したい性質
停止性
多くの場合,系のある値が各ステップで減少
すること,そのような降下列(decreasing
sequence)は常に有限であることを示すことに
帰着
f : C W (W : well-founded set. 無限の降下
列を持たない集合(例 : 自然数))
c c’ならばf(c) > f(c’)
例題の続きと証明
デッドロック防止の基本アイデア: AとBが衝
突したらAが勝つ
• AはBにnegative ackを送る
• Bはnegative ackを受け取ったらlockを解除してA
のrequestを実行
明文化されていない仮定
updateは有限回しか実行されない
証明のための単純な明文化(高々N回)
•
i > 0 && !locked
send(him, update(me)); locked = 1; i--;
| i > 0 && !locked i--;
| … (以下同様) …
また,同一プロセスペア間のメッセージ順序の保存
を仮定する(先に送ったほうが先に届く)
i = N;
/* 高々あと何回updateを送るか */
req = 0;
/* 相手からの未処理リクエスト */
locked = 0; /* 自分が相手にリクエスト中 */
while (1) {
i > 0 && !locked
1
i--;send(him, update); locked = 1;
2 | i > 0 && !locked i--;
3 | received(update) req = 1;
4 | req && !locked p = him; req = 0; send(him, ok);
5 | req && locked && me < him req = 0; send(him, ng);
6 | received(ok) locked = 0; p = me;
7 | received(ng) locked = 0;
}
正しさの表明
任意の実行の長さは有限
任意の終了状態(これ以上の遷移がない状
態)において,
• lockedA = lockedB = 0
• reqA = reqB = 0
• pA = pB
「実行の長さ有限」の証明
ほとんど明らか(updateは有限回しか送られない.ひ
とつのupdateメッセージからは有限個の状態遷移し
かおこらない)
正式な証明は,各遷移で「何か」の値が狭義に減少
することを示す.その値とは以下の組に辞書順(上
の要素ほど優先)で順序を入れたもの
•
•
•
•
i
M中のupdateメッセージの個数
reqの値
M中のok/ngメッセージの個数
正しい終了
任意の実行 C = c1 c2 … cnをfix
正しそうな表明:
• この実行中で実行された
• received(ok) locked = 0; p = me;
• の遷移のうち,最後のものによって最終結果が
決まっているのだろう(つまり,もう一方のプロセ
スのpも同じ値で,かつlocked = req = 0)
pの一致
C中で最後に実行された
• received(ok) locked = 0; p = me;
の遷移をeとする.これを実行したプロセスをx,
もう一方のプロセスをyとする.
eが実行可能となるためには少なくとも一回,
yでsend(him, ok)が実行される必要があるか
ら,そのような最後の遷移をe1とする.以降で
は,C中でe1以降,yによるpへの代入(遷移4,
6)がおきないことを言う
e1以降yの遷移4はない
e1が,eに先立つyによるsend(him, ok)のうち
最後のものであるという仮定に反する
e1以降yの遷移6はない
e1が実行可能となるには,少なくとも一回,x
でsend(him, update)が実行される必要がある.
そのような最後の遷移をe2とする. e2実行後
lockedx = 1であり,eまでそうあり続ける(要詳
細化).したがってe以前に実行されたxによる
send(him, ok)は,(あるとすれば) e2以前のも
のである.したがって,メッセージ順序の保存
より,yによるreceived(ok)は,あるとすればe1
に先立つ
locked = 0 (B)
Bによる,最後のlockedB = 1 (遷移1)が実行さ
れたら,いずれlockedB = 0 (遷移6, 7)が実行
される.実際,
• Aはいずれreceived(update) (遷移3)を実行
• Aはいずれ遷移4 or 5を実行
• Bはいずれ遷移6 or 7を実行
つまり,最終状態でlockedB = 0
locked = 0 (A)
Aによる最後のlockedA = 1 (遷移1)が実行されたら,
いずれlockedA = 0 (遷移6, 7)が実行される.実際,
• Bはいずれreceived(update) (遷移3)を実行(e’とする)
• Bが最後にlockedB = 1 lockedB = 0となった遷移をeとす
る.これ以降ずっとlockedB = 0に注意
• …, e, …, e’, …の場合:Bはいずれ遷移4を実行
• …, e’, …, e, …の場合:eまでにBが遷移4を実行しなければ,e直
後でなおreqB = 1.結局Bはいずれ遷移4を実行
• Aはいずれ遷移6 or 7を実行
つまり,最終状態でlockedA = 0
req = 0
最終状態ではlocked = 0である.ここでreq = 0
ならば遷移3が実行可能となり,それは最終
状態ではない
非同期メッセージパッシングプログラ
ムの性質と重要概念
用語: 遷移(transition)の代わりに事象(event)
ということもある
因果順序
ある実行Cを考える.C中のeventの因果順序
(causal order) とは以下を満たす最小の半
順序関係
• C中で…, a, …, b, … の順に現れ,a, bが同じプロ
セスのeventならばa b
• C中で…, a, …, b, … の順に現れ,aがあるメッ
セージの送信,bがその受信ならばa b
因果順序の性質
ある実行Cに対し,すべての因果順序を保っ
たまま,eventの順番を入れ替えても,それは
正しい実行であり,同じ最終状態に到達する
直感的な意味: 因果順序にないeventが実行
された順番は観測不可能
• 互いに通信しないプロセス同士の内部遷移が
「どっちが先立ったか?」と問うても無駄
因果順序の性質(続)
「実行」は因果順序を拡張したeventの全順序
で,神のみが知る
Event間の因果順序こそが,特定のプログラ
ムの実行を特徴付け(他の実行と区別し)てい
る
メッセージパッシングプログラムの実
行の図示
A
B
C
D
このような,横軸に時間,縦軸にプロセスを
とった図で表すことが多い.プロセス間のメッ
セージは斜めの線で表す
有用な見方
この図示はevent間の因果順序を表している
と見ることもできる.より正確には,
メッセージの矢印の根元に送信event, 先端に
受信event, 水平線の各所に内部遷移がある
と思うと,
a b 図上でaからbへ矢印の道がある
メッセージ図
= eventの因果順序関係の図示
A
B
C
D
メッセージ図と「実行」
A
B
C
D
神様はメッセージ図に示された矢印間の順序
は保ちながら次に実行するeventを任意に選
択していた…
実行
神様が実際に選択したeventの実行順序(全
順序)を知るすべはないが,「もっともらしい」
「観測と矛盾しない」実行順序を作ることは容
易である
• 因果順序を保った順序であればなんでもよい
aba<b
を満たす順序であればなんでもよい(そう考えても
矛盾はきたさない)
時計(Clock)
ある実行中のevent eに対して割り当てられた値C(e)
で,
a b C(a) < C(b)
を満たすものを時計という
例
• 正確に実時間と同期した時計があれば,もちろんそれは
時計である
• 神様が実行したeventの全順序を知ることができれば,
C(a) = その全順序でのaの位置
もまた(実現不可能な)時計である
Lamportの論理時計
簡単に実現可能な時計
int Cp : (pの時刻)
初期化 Cp := 0
内部遷移: t = Cp ; Cp = t + 1;
send(m):
t = Cp ; mに時刻印t + 1を付加;
t = Cp + 1;
recveived(m) :
t = max(Cp , mの時刻印); Cp = t + 1;
Lamportの論理時計の簡単な応用:
実行の再現
並列実行中:各eventに論理時計を付加して
記録(logging)
再現実行中:論理時刻が小さい順にeventを
実行
公平性(Fairness)
停止性を「任意の実行系列」に対して証明す
ることは不可能であることが多い
• 例: どんなアルゴリズムでも,常に実行可能な無
意味な状態遷移をひとつ付け加えるだけで,常に
「終了しない実行」が可能になってしまう
証明の対象となる実行にある種の制限(公平
性; fairness)を設けることが必要になる
Weak Fairness
ある実行がweakly fairとは,
もう少し複雑な例題
極大木構築
G = V, E プロセスのネットワーク
• V : プロセス, E : 通信できるプロセスペア
各プロセスは自分の近隣ノード(neighbors)を
与えられる
問題:
• 各プロセスで変数 parent を計算
• parentをポインタとしたグラフがEの生成木になっ
ている
10/18 加藤(数理), …
10/25 今竹,堀田
11/15 ふじた はやつ
11/22 林
11/29 吉本(電子情報),吉田
12/6 初田, 豊島
© Copyright 2026 ExpyDoc