240 likes | 379 Views
A Type and Effect System for Deterministic Parallel Java. Robert Bocchino , et al. Universal Parallel Computing Research Center University of Illinois. Presented by Thawan Kooburat Computer Science Department University of Wisconsin - Madison.
E N D
A Type and Effect System forDeterministic Parallel Java Robert Bocchino, et al. Universal Parallel Computing Research Center University of Illinois Presented by Thawan Kooburat Computer Science Department University of Wisconsin - Madison *Based on OOPSLA-2009 conference presentation by Robert Bocchino
Outline Prologue Introduction Deterministic Parallel Java (DPJ) Usage Patterns Implementation Evaluation
Prologue • ParallelArray (Java 7 – java.util.concurrent) • Slice up data into blocks • Perform operation on all data concurrently
Prologue ParallelArray of distinct objects Time Access global variables Framework cannot prevent programmer from writing code will break the semantic
Introduction • Deterministic Execution • Same input always produce same output • Many computational algorithms are deterministic • Many programs use parallel execution in order to gain performance , but it is not part of the specification.
Deterministic-by-default • Guaranteed deterministic execution by default • Nondeterministic behavior must be explicitly requested. • foreach • Iterating over independent objects • foreach_nd • Iterating over overlapping objects R. Bocchino, V. Adve, S. Adve, and M. Snir, “Parallel Programming Must Be Deterministic by Default”
Benefits • Can reason sequentially • No hidden parallel bugs • Testing based on input • No need to test all interleaving combinations • Parallelize incrementally • Easier to compose
Deterministic Parallel Java (DPJ) • Based on Java language • Fork/Join parallelism • Cobegin • Foreach • Type and effect system • Expose noninterference (Soundness) • Field-level granularity • Differentiate between readers and writers • Guarantee deterministic execution at compile time
Regions and Effects • Regions • Divide memory location into regions • Can be formed into a tree Parameterized by region class TreeNode<region P> { region L, R, V; int value in V; TreeNode<L> left = new TreeNode<L>(); TreeNode<R> right = new TreeNode<R>(); }
Regions Root Root:L Root:R Root:L:L Root:L:R Root:R:L Root:R:R
Effects • Effects • Read or write operations on data • Programmer specify effect summary for each method class TreeNode<region P> { ... TreeNode<L> left = new TreeNode<L>(); TreeNode<R> right = new TreeNode<R>(); void updateChildren() writesL, R { cobegin { left.data = 0; /* writesL*/ right.data = 1; /* writesR*/ } } Method effect summary Non interference Compiler inferred from type
Usage Patterns • Region path lists (RPLs) • Updating nested data structure with field-granularity • Index-parameterized array • Updating an array of objects • Subarray • Partition array for divide and conquer pattern. • Commutativity • Declare effect summary based on operation’s semantic
Region Path Lists (RPLs) class Tree<region P> { region L, R; int value in P; Tree<P:L> left = new Tree<P:L>(); Tree<P:R> right = new Tree<P:R>(); } P= Root value Root left Root:L right Root:R P=Root:L P=Root:R value Root:L value Root:R left Root:L:L left Root:R:L right Root:L:R right Root:R:R
Region Path Lists (RPLs) class Tree<region P> { ... int increment() writes P:* { value++; /* writes P */ cobegin { /* writes P:L:* */ if (left != null) left.increment(); /* writes P:R:* */ if (right != null) right.increment(); } } Method effect summary Effect inferred from type and summary Inclusion (Method effect) P:L:* ⊆ P:* P:R:* ⊆ P:* Disjointness (Cobegin body) P:L:* ∩ P:R:* = ∅
Index-parameterized Array Enforce disjointness of array’s element (reference) Syntax: C<[i]>[]#i 1 2 3 4 1 2 3 4 a[i] b[i] 1 2 3 4 c[i] C<[1]> C<[2]> C<[3]> C<[4]>
Index-parameterized Array class Body<region P> { double mass in P:M; double force in P:F; Body <*> link in Link; void computeForce() readsLink, *:Mwrites P:F {..} } final Body<[_]>[]<[_] > bodies = new Body<[_]>[N]<[_]>; foreach (inti in 0, N) { /* writes [i] */ bodies[i] = new Body<[i]> (); } foreach (inti in 0, N) { /* reads [i], Link, *:Mwrites [i]:F */ bodies[i].computeForce(); Objects are parameterlized by index region Write to each element is distinct Operations in foreach block is noninterference Read does not interfere write
Subarray • Mechanisms: DPJ Libraries • DPJArray: Wrapper class for Java array • DPJPartition: Collections of disjoint DPJArray • Divide and Conquer usage pattern • Initialize an array using DPJArray • Recursively partition original array using DPJPartition • Each partition is a disjoint subset of original array • Create a tree of partition based on flat array
Subarray static <region R>void quicksort(DPJArray<R> A) writes R:* { int p = quicksortPartition(A); /* Chop array into two disjoint pieces */ final DPJPartition<R> segs = new DPJPartition<R>(A, p, OPEN); cobegin { /* write segs:[0]:* */ quicksort(segs.get(0)); /* write segs:[1]:* */ quicksort(segs.get(1)); } } Use local variable to represent regions R DPJArray segs[0] p segs[1] DPJPartition
Commutativity • Method annotation • Allow programmers to override effect system • Compiler will not check inside the method • This allows cobegin { add(e1); add(e2); } • Any order of operations is equivalent • Operation is atomic interface Set<type T, region R> { commutative void add(T e) writes R; }
Commutativity Method invocation foreach (inti in 0, n) { /* invokes Set.add with writes R */ set.add(A[i]); } cobegin { /* invokes Set.add with writes R */ set.add(A); /* invokes Set.size with read R */ set.size(); }
Implementation • Extend Sun’s javac compiler • Covert DPJ into normal Java source • Compile to ForkJoinTask Framework (Java7) • Similar to Cilk • DPJ translates foreach and cobegin to tasks
Evaluation Benchmarks
Performance 24 Barnes-Hut Mergesort IDEA K-Means Collision Tree Monte Carlo 20 Speedup 16 12 8 4 4 8 12 16 20 24 Number of cores