Transactional Memories: a theoretical introduction Selim Arsever & Pascal Perez
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A A<w,r> | A<w,r> | M<w,r,v> = w<v>.WORK.r(v').[v'=v].A | w<v>.WORK.r(v').[v'=v].A | w(f).M<w,r,f> + r<v>.M<w,r,v>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[v'=a].A | w<v>.WORK.r(v').[v'=v].A | w(a).M<w,r,f> + r<v>.M<w,r,v>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[v'=a].A | w<v>.WORK.r(v').[v'=v].A | w(a).M<w,r,a> + r<v>.M<w,r,v>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[v'=a].A | w<v>.WORK.r(v').[v'=v].A | w(a).M<w,r,a> + r<v>.M<w,r,v>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[v'=a].A | w<v>.WORK.r(v').[v'=v].A | w(f).M<w,r,f> + r<a>.M<w,r,a>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[v'=a].A | w<b>.WORK.r(v').[v'=b].A | w(b).M<w,r,b> + r<a>.M<w,r,a>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[v'=a].A | w<b>.WORK.r(v').[v'=b].A | w(b).M<w,r,b> + r<a>.M<w,r,a>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[v'=a].A | w<b>.WORK.r(v').[v'=b].A | w(f).M<w,r,f> + r<b>.M<w,r,b>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[b=a].A | w<b>.WORK.r(v').[v'=b].A | w(f).M<w,r,f> + r<b>.M<w,r,b>
Shared Memory Problems M(w,r,v) := w(f).M<w,r,f> + r<v>.M<w,r,v> A(w,r) := w<v>.WORK.r(v').[v'=v].A → w<a>.WORK.r(v').[b=a].A | w<b>.WORK.r(v').[v'=b].A | w(f).M<w,r,f> + r<b>.M<w,r,b>
Locking is dangerous ● What if a thread fails whilst holding a lock? ● Deadlocks happen! ● Linux pros on http://lwn.net/Articles/86859/
Locking does not scale well Fine grained locked data structures implementation exist of the shelf but… Global knowlegde!
Transaction A tomicity C onsistency I solation D urability
Transaction A + B + C should remain constant under the execution of both transactions in any order. Correct: Wrong: A = A – 10 lock L 1 lock L 1 lock L 2 lock L 1 B = B – 20 A = A – 10 B = B – 20 B = B + 10 unlock L 1 unlock L 1 unlock L 2 unlock L 1 C = C + 20 B = B + 10 C = C + 20
R(0) Transactional Memory W(0) W(1) R(1) W(0) A B C
R(1) Transactional Memory W(0) W(1) R(1) W(0) A B C
Transactional Memory Initial Situation: M T 1 n b TM T 2 T 3
Transactional Memory T 1 gives his chanels to TM: M T 1 n b TM {o,g,a,c,x}
Transactional Memory T 1 gets it’s copie of M: } ’ r , ’ w M’ { M T 1 n b TM {o,g,a,c,x}
Transactional Memory T 1 tries to commit: } ’ r , ’ w M’ { M T 1 n b TM {o,g,a,c,x} T 2 T 3
Transactional Memory A new TM is created: } ’ r , ’ w M 1 { M T 1 n b TM {o,g,a,c,x} M ’ n’’ T 2 TM’ T 3
Concurrent Commit T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : c 2 .(c 2 + x 2 .T 2 <b>) TM : crash | !... | k.x 1 | k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | c 2 .crash.n 2 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 2 )
Concurrent Commit T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : c 2 .(c 2 + x 2 .T 2 <b>) TM : crash | !... | k.x 1 | k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | c 2 .crash.n 2 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 2 )
Concurrent Commit T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : c 2 .(c 2 + x 2 .T 2 <b>) TM : crash | !... | k.x 1 | k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | c 2 .crash.n 2 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 2 )
Concurrent Commit T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : c 2 .(c 2 + x 2 .T 2 <b>) TM : crash | !... | k.x 1 | k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | c 2 .crash.n 2 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 2 )
Concurrent Commit T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : c 2 .(c 2 + x 2 .T 2 <b>) TM : crash | !... | k.x 1 | k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | c 2 .crash.n 2 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 2 )
Concurrent Commit T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : c 2 .(c 2 + x 2 .T 2 <b>) TM : crash | !... | k.x 1 | k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | c 2 .crash.n 2 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 2 )
Concurrent Commit T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : c 2 .(c 2 + x 2 .T 2 <b>) TM : crash | !... | k.x 1 | k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | c 2 .crash.n 2 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 2 )
Concurrent Commit T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : c 2 .(c 2 + x 2 .T 2 <b>) TM : crash | !... | k.x 1 | k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | c 2 .crash.n 2 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 2 )
Exceptions Enhancement Avoiding Unnecessary Exceptions ● TM := (… | !p(x,cancel).(k.x + cancel)) G := … ( v cancel)(p<x,cancel>. … .(… | cancel.!k) Allowing Needed Exceptions ●
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | p(x).k.x | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | p(x).k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Commit while Starting T 1 : c 1 .(c 1 + x 1 .T 1 <b>) T 2 : b<o 2 ,g 2 ,a 2 ,c 2 ,x 2 >.o.g … TM : crash | !... | k.x 1 | p(x).k.x 2 | ! p(x).k.x | c 1 .crash.n 1 ’(w’’,r’’,n’’).(TM<b,n’’>| !k | c 1 ) | b(o 2 ,g 2 ,a 2 ,c 2 ,x 2 ).p<x 2 >.o …
Recommend
More recommend