五、 Conclusion
從本文的實際演練中觀察到的幾個現象,做出以下的推論:
(1) generic approach 適用於任何 mutual exclusion algorithm of atomic read/write model。
(2) 2-dimensional permitted bits 的方式適用於具 starvation 的 algorithm,如:
Dijkstra’s[4]、Burns’[2]。
(3) 2-dimensional permitted bits 的方式適用於 one-writer/multiple-reader mutual exclusion algorithm,如:Lamport’s bakery[8]、Burns’[2]。
(4) fast track 依賴 focused release 而存在。
(5) 具 starvation 的 algorithm 很難找到 focused release,如:Dijkstra’s[4]、
Burns’[2]。
(6) 具 bounded waiting 的 algorithm 可以找到 focused release,如:Knuth’s[6]、
Eisenburg-McGuire’s[5]、Lamport’s bakery[8]。
(7) one-writer/multiple-reader mutual exclusion algorithm 的 S-loop 有機會加上 local spin,如:Lamport’s bakery[8]、Burns’[2]。
雖然上述的現象只是從本文中演練的 algorithm 中歸納出來,目前尚不能推廣到所 有的 mutual exclusion algorithm,但就邏輯上的推演並不無道理,詳述如下。
(1) 如第三章描述。
(2) 會發生 starvation 的 algorithm 通常都會讓 processes 進行激烈的競爭,何者 可以進入 CS 可以說完全是隨機因素決定,也因為如此,使用 2-dimensional permitted bits 加 上 local spin 機 制 時 , 雖 然 在 釋 放 過 程 只 有 部 分 local-spinning processes 被釋放,但是這些被釋放的 local-spinning processes 在進行激烈的競爭時,仍然有能力進入 CS。
(3) one-writer/multiple-reader mutual exclusion algorithm 有一個通則,就是 process 要獲得彼此之間的狀態只能透過 linear reading 其它 process 專屬的 shared variable 方可得知,也因為如此,這類的 algorithm 無論在 P-loop 或 S-loop 測試失敗後,通常還是持續進行 linear reading 的動作,一直到阻礙 的因素解除為止,那麼使用 2-dimensional permitted bits 來加上 local spin 機制不會造成 dead lock 的原因就在於行為上正是符合這樣的特性,只是 反過來由造成其它 process 進入 local spin 的 process 主動通知(釋放)
local-spinning processes 可以繼續原本該有的行為,如此而已。
(4) 沒有 focused release 就沒有辦法分辨哪個 process 有機會進入 CS,更不能 分辨哪個 process 確定可以進入 CS。
(5) 會發生 starvation 的 algorithm 無法確定 processes 進入 CS 的順序,所以無 法使用 focused release 還能確保不發生 dead lock。
(6) 具備 bounded waiting 性質的 algorithm 會利用某種機制使得 process 不能連 續進入 CS 兩次以上,也就是說,這樣的機制會使得部份 processes 失去競 爭的優勢,那麼只要在 exit region 利用反向機制找到仍然具備競爭優勢的 process,它就是 focused release 的標的。
(7) 理由與(3)是一樣的,algorithm 中反覆進行 linear reading 的 loop 若為 S-loop,那麼加上 local spin 也不會造成 dead lock。
綜合上述的演練經驗,不具備 bounded waiting(starvation freedom)的 mutual exclusion algorithm 建議採用 2-dimensional permitted bits 的方式加上 local spin 比較有助 於 memory contention 的降低;具備 bounded waiting 的 mutual exclusion algorithm 則建議 採用 the generic approach 以及添加 focused release,在 heavy loading 的狀況下會有較佳 的表現。
本 文 的 特 點 包 含 成 功 找 出 recursive function 來 證 明 Knuth’s mutual exclusion algorithm 具 備 2n−1−1 bounded waiting 性 質 ; 利 用 一 個 Lemma 即 證 明 Eisenburg-McGuire’s mutual exclusion algorithm 加上 focused release、fast track 的正確性,
以及具備n−1 bounded waiting 性質;發現使用 2-dimensional permitted bits 加上 local spin 的方法並不適用於任何 mutual exclusion algorithm;利用 tree 的結構來分析 the generic approach 和 2-dimensional permitted bits 的差異。
參 考 文 獻
[1] James H. Anderson and Yong-Jik Kim, “A new fast-path mechanism for mutual exclusion”, Springer-Verlag Distributed Computing, Volume 14, Issue 1, January, 2001, Pages 17-29.
[2] James E. Burns, “Mutual exclusion with linear waiting using binary shared variables”, ACM SIGACT News, Volume 10, Number 2, Summer, 1978, Pages 42-47.
[3] Sheng-Hsiung Chen and Ting-Lu Huang, “A Tight Bound on Remote Reference Time Complexity of Mutual Exclusion in the Read-Modify-Write Model”, Journal of Parallel and Distributed Computing, Volume 66, Issue 11, November, 2006, Pages 1455-1471.
[4] Edsger Wybe Dijkstra, “Solution of a problem in concurrent programming control”, Communications of the ACM, Volume 8, Issue 9, September, 1965, Pages 569.
[5] Murray A. Eisenberg and Michael R. McGuire, “Further comments on Dijkstra's concurrent programming control problem”, Communications of the ACM, Volume 15, Issue 11, November, 1972, Pages 999.
[6] Donald E. Knuth, “Additional comments on a problem in concurrent programming control”, Communications of the ACM, Volume 9, Issue 5, May, 1966, Pages 321-322.
[7] Leslie Lamport, “A Fast Mutual Exclusion Algorithm”, ACM Transactions on Computer Systems, Volume 5, Number 1, February 1987, Pages 1–11.
[8] Leslie Lamport, “A new solution of Dijkstra's concurrent programming problem”, Communications of the ACM, Volume 17, Issue 8, August, 1974, Pages 453-455.
[9] Nancy A. Lynch, Distributed Algorithms, Morgan Kaufmann, 1996.
[10] John M. Mellor-Crummey and Michael L. Scott, “Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors”, ACM Transactions on Computer Systems, Volume 9, Number 1, February, 1991, Pages 21-65.
[11] Gadi Taubenfeld, Synchronization Algorithms and Concurrent Programming, Prentice Hall, 2006.
[12] Yih-Kuen Tsay, “Deriving a Scalable Algorithm for Mutual Exclusion”, Lecture notes in computer science, Springer Berlin, Vol. 1499, 1998, Pages 393-407.
[13] Jae-Heon Yang and Jams H. Anderson, “A fast, scalable mutual exclusion algorithm”, Springer Berlin / Heidelberg Distributed Computing, Volume 9, Number 1, March, 1995, Pages 51-60.
附 錄
Gary L. Peterson's n-processes mutual exclusion algorithm and its variation (1) The original version: Algorithm P0
Shared variables:
z for every k, 1≤k≤n−1, last(k)∈{0,K,n−1}, initially arbitrary, writable and readable by all processes
z for every i, 0≤i≤n−1, flag(i)∈{0,K,n−1}, initially 0, writable by process i and readable by all processes
Process i:
(private variable j: integer, k: integer) R: ** Remainder Region **
T1: for k=1 to n−1 do T2: flag(i):=k T3: last(k):=i
T4: for 0j= to n−1, j≠ do i
T5: while( flag(j)≥ flag(i) and last(k)=i) do nothing od
T6: od
T7: od C: ** CS **
E: flag(i):=0
R: ** Remainder Region **
(2) Adding local spin to P0 by using 2-dimensional permitted bits: Algorithm P1
Shared variables:
z for every k, 1≤k≤n−1, last(k)∈{0,K,n−1}, initially arbitrary, writable and readable by all processes
z for every i, 0≤i≤n−1, flag(i)∈{0,K,n−1}, initially 0, writable by process i and readable by all processes
z for every i, j , k, 0≤i≤n−1, 0≤ j≤n−1, 1≤k≤n−1,
(3) Adding local spin to P0 by the generic approach: Algorithm P2
Shared variables:
z for every k, 1≤k≤n−1, last(k)∈{0,K,n−1}, initially arbitrary, writable and readable by all processes
z for every i, 0≤i≤n−1, flag(i)∈{0,K,n−1}, initially 0, writable by process i and readable by all processes
z for every i, k, 0≤i≤n−1, 1≤k≤n−1, permitted(i,k)∈{true,false}, writable by all processes and readable by process i
Process i:
(private variable j: integer, k: integer) R: ** Remainder Region **
T1: for k=1 to n−1 do T2: permitted(i,k):= false T3: flag(i):=k
T4: last(k):=i
T5: for j=0ton−1,j≠idopermitted(j,k):=trueod T6: for 0j= to n−1, j≠ do i
T7: while( flag(j)≥ flag(i) and last(k)=i) do
T8: await permitted(i,k)
T9: permitted(i,k):= false
T10: od
T11: od
T12: od
C: ** CS **
E1: flag(i):=0
E2: fork=1ton−1do
E3: for j=0ton−1do permitted(j,k):=trueod E4: od
R: ** Remainder Region **
(4) Adding focused release to P2: Algorithm P3
Shared variables:
z for every k, 1≤k≤n−1, last(k)∈{0,K,n−1}, initially arbitrary, writable and readable by all processes
z for every i, 0≤i≤n−1, flag(i)∈{0,K,n−1}, initially 0, writable by process i and readable by all processes
z for every i, k , 0≤i≤n−1, 1≤k≤n−1, permitted(i,k)∈{true,false}, writable by all processes and readable by process i
Process i:
(private variable j: integer, k: integer, next: integer) R: ** Remainder Region **
T1: for k=1 to n−1 do T2: permitted(i,k):= false T3: flag(i):=k
T4: last(k):=i
T5: for j=0ton−1,j≠idopermitted(j,k):=trueod T6: for 0j= to n−1, j≠ do i
T7: while( flag(j)≥ flag(i) and last(k)=i) do
T8: await permitted(i,k)
T9: permitted(i,k):= false
T10: od
T11: od
T12: od
C: ** CS **
E1: next:=last(n−1) E2: flag(i):=0 E3: if(next=i)then
E4: fork=1ton−1do
E5: for j=0ton−1do permitted(j,k):=trueod
E6: od
E7: else permitted(next,n− :1) =true fi >focused release R: ** Remainder Region **