Dete term rministic inistic P Paralle llel Sc l Scripting: ripting: Ma Making the ing the Ea Easy C sy Case se Ea Easy sy Michael L. Scott www.cs.rochester.edu/u/scott/ Dagstuhl, January 2015 MLS ! 1 !
Whe Where re in the in the C Curric urriculum ulum? computer literacy data structures graphics, HCI, web computing networks, dist. comp. languages, SW engg., sci. comp. OS, arch., par. comp., DBMS MLS ! 2 !
Wha What La t Langua nguage ge D Do We o We U Use se? ● Lamport: This is the wrong question. » � Imagine an art historian answering � how would you describe impressionist painting? � by saying � in French. �� ● MLS: This is the wrong analogy. » Imagine an art teacher answering � how would you introduce pointillism? � by saying � in oils. � ● Notation matters! MLS ! 3 !
Whe Where re D Doe oes Ea s Easine siness Ma ss Matte tter? r? ● Dynamic (scripting) languages! » Increasing share of modern programs in Python, Ruby, PHP, Matlab, R, JavaScript, . . . » Increasing share of introductory curricula » Ease of programming trumps performance » But concurrency can still make a difference on multicore machine ● Deterministic Parallel Ruby (DPR) » Thesis work of Li Lu (now at Hortonworks)\ » Emphasis on independence & proper nesting MLS ! 4 !
DPR PR C Construc onstructs (1 ts (1) ● Independent blocks (co operator): def qsort(a) return a if a.length <= 1 m = a.length/2 pivot = a[m] left = qsort(a.select{|v| v < pivot}) mid = a.select{|v| v == pivot} right = qsort(a.select{|v| v > pivot}) return left + mid + right end MLS ! 5 !
DPR PR C Construc onstructs (1 ts (1) ● Independent blocks (co operator): def qsort(a) return a if a.length <= 1 m = a.length/2 pivot = a[m] left = qsort(a.select{|v| v < pivot}) mid = a.select{|v| v == pivot} right = qsort(a.select{|v| v > pivot}) return left + mid + right end MLS ! 6 !
DPR PR C Construc onstructs (1 ts (1) ● Independent blocks (co operator): def qsort(a) return a if a.length <= 1 m = a.length/2 pivot = a[m] co ->{ left = qsort(a.select{|v| v < pivot}) }, }, ->{ mid = a.select{|v| v == pivot} }, ->{ right = qsort(a.select{|v| v > pivot}) } return left + mid + right end MLS ! 7 !
DPR PR C Construc onstructs (2 ts (2) ● Independent unordered iteration: myset.all {|e| op } ● Reductions: sum = Reduction.new(IntegerAdd) myset.all {|e| sum.push(1) if P(e) } count = sum.get MLS ! 8 !
DPR PR C Construc onstructs (3 ts (3) ● Atomic commutative operations — consider: sum = Reduction.new(IntegerAdd) myset.all {|e| sum.push(f(e)) } where f is a very expensive function. Instead, do: mtab = new MemoTable(f) sum = Reduction.new(IntegerAdd) myset.all {|e| sum.push(mtab.eval(e)) } where MemoTable is defined (in advance, by an expert) as ... MLS ! 9 !
DPR PR C Construc onstructs (3 ts (3) class MemoTable def eval(key) def initialize(f) atomic @f = f val = @table[key] @table = Hash.new end end if val == nil val = @f.call(key) atomic @table[key] = val end self.setACOps :eval end end return val end MLS ! 10 !
DPR PR C Construc onstructs (4 ts (4) ● Pure futures: f = Future.new(->{|x1, x2, ...| op }, arg 1 , arg 2 , ...) ... v = f.get() ● Pipelines p = ->{|x| s1} >> ->{|x| s2} >> ->{|x| s3} p.setInStream(MyInStream.new) p.setOutStream(MyOutStream.new) p.run » Stage i on object n must be independent of stage j on object m if (and only if) i+n = j+m MLS ! 11 !
DPR PR Im Imple plementa ntation tion ● Tiny sequential library (few dozen lines); (larger) parallel library » Both run on any Ruby VM ● Built-in version on JRuby » Thread pool with Cilk-like work stealing scheduler » Modest scalability: 2-6x on 12 cores ● Independence treated as an assertion » Checked at run-time: TARDIS determinism checker [ PLDI’14 ] » Cf. subscript or type checking • Not solid enough to use for teaching yet ! » But I really think something along these lines is what we need MLS ! 12 !
www.cs.rochester.edu / u / scott /
Recommend
More recommend