composable specifications for structured shared memory
play

Composable Specifications for Structured Shared-Memory Communication - PowerPoint PPT Presentation

Composable Specifications for Structured Shared-Memory Communication Benjamin P . Wood , Adrian Sampson, Luis Ceze, Dan Grossman University of Washington 1 Code-Communication Specifications Writer Thread Reader Thread enqueue(...);


  1. Communication Modules Module Specification package pipeline; package buffer; public class BoundedBuffer { import buffer.BoundedBuffer; � Item[] buffer = new Item[10]; class Pipeline { � int size = 0; � BoundedBuffer pipe; � � public synchronized void enqueue( Item i ) { � // Producer threads � � while ( size == buffer.length) wait(); � void produce () { � � buffer[ ... ] = i ; ... pipe. enqueue(...) ; ... � � size++; ... � } � � notifyAll(); � } � // Consumer threads � void consume () { � public synchronized Item dequeue() { � ... = pipe. dequeue() ; ... � � while ( size == 0) wait(); � } � � size--; ... } � � notifyAll(); � � return buffer[ ... ]; � } } 9

  2. Communication Modules Module Specification package pipeline; package buffer; public class BoundedBuffer { import buffer.BoundedBuffer; � Item[] buffer = new Item[10]; class Pipeline { � int size = 0; � BoundedBuffer pipe; � � public synchronized void enqueue( Item i ) { � // Producer threads � � while ( size == buffer.length) wait(); � void produce () { � � buffer[ ... ] = i ; ... pipe. enqueue(...) ; ... � � size++; ... � } � � notifyAll(); � } � // Consumer threads � void consume () { � public synchronized Item dequeue() { � ... = pipe. dequeue() ; ... � � while ( size == 0) wait(); � } � � size--; ... } � � notifyAll(); � � return buffer[ ... ]; � } } 9

  3. Checking Communication Specifications Writer Thread Reader Thread in produce(...): in consume(...): in enqueue(...): in dequeue(...): buffer[3] = ...; return buffer[3]; 10

  4. Checking Communication Specifications Writer Thread Reader Thread in produce(...): in consume(...): in enqueue(...): in dequeue(...): buffer[3] = ...; return buffer[3]; 10

  5. Checking Communication Specifications Writer Thread Reader Thread in produce(...): in consume(...): in enqueue(...): in dequeue(...): buffer[3] = ...; return buffer[3]; 11

  6. Checking Communication Specifications Writer Thread Reader Thread in produce(...): in consume(...): ✔ in enqueue(...): in dequeue(...): buffer[3] = ...; return buffer[3]; 11

  7. Checking Communication Specifications Writer Thread Reader Thread ✔ in produce(...): in consume(...): ✔ in enqueue(...): in dequeue(...): buffer[3] = ...; return buffer[3]; 11

  8. Checking Communication Specifications ✔ Writer Thread Reader Thread ✔ in produce(...): in consume(...): ✔ in enqueue(...): in dequeue(...): buffer[3] = ...; return buffer[3]; 11

  9. Communication Module Interfaces Writer Thread Reader Thread in consume(...): in produce(...): in dequeue(...): in enqueue(...): size--; ... = size; 12

  10. Communication Module Interfaces Writer Thread Reader Thread in consume(...): in produce(...): ✔ in dequeue(...): in enqueue(...): size--; ... = size; 12

  11. Communication Module Interfaces Writer Thread Reader Thread ✘ in consume(...): in produce(...): ✔ in dequeue(...): in enqueue(...): size--; ... = size; 12

  12. Communication Module Interfaces Module Specification package pipeline; package buffer; public class BoundedBuffer { import buffer.BoundedBuffer; � Item[] buffer = new Item[10]; class Pipeline { � int size = 0; � BoundedBuffer pipe; � � public synchronized void enqueue( Item i ) { � // Producer threads � � while ( size == buffer.length) wait(); � void produce () { � � buffer[ ... ] = i ; ...; pipe. enqueue(...) ; ... � � size++; ... � } � � notifyAll(); � } � // Consumer threads � void consume () { � public synchronized Item dequeue() { � ... = pipe. dequeue() ; ... � � while ( size == 0) wait(); � } � � size--; ... } � � notifyAll(); � � return buffer[ ... ]; � } } 13

  13. Communication Module Interfaces Module Specification package pipeline; package buffer; public class BoundedBuffer { import buffer.BoundedBuffer; � Item[] buffer = new Item[10]; class Pipeline { � int size = 0; � BoundedBuffer pipe; � � public synchronized void enqueue( Item i ) { � // Producer threads � � while ( size == buffer.length) wait(); � void produce () { � � buffer[ ... ] = i ; ...; pipe. enqueue(...) ; ... � � size++; ... � } � � notifyAll(); � } � // Consumer threads � void consume () { � public synchronized Item dequeue() { � ... = pipe. dequeue() ; ... � � while ( size == 0) wait(); � } � � size--; ... } � � notifyAll(); � � return buffer[ ... ]; � } } Module Interface 13

  14. Communication Module Interfaces Writer Thread Reader Thread ✘ in consume(...): in produce(...): ✔ in dequeue(...): in enqueue(...): size--; ... = size; 14

  15. Communication Module Interfaces Writer Thread Reader Thread in consume(...): in produce(...): ✔ in dequeue(...): in enqueue(...): size--; ... = size; 14

  16. Communication Module Interfaces Writer Thread Reader Thread in consume(...): in produce(...): ✔ in dequeue(...): in enqueue(...): size--; ... = size; 15

  17. Communication Module Interfaces ✔ Writer Thread Reader Thread in consume(...): in produce(...): encapsulated ✔ in dequeue(...): in enqueue(...): size--; ... = size; 15

  18. Communication Inlining Writer Thread Reader Thread in enqueue(...): in arrayCopy(...): in dequeue(...): buffer[3] = ...; return buffer[3]; 16

  19. Communication Inlining Writer Thread Reader Thread in enqueue(...): in arrayCopy(...): in dequeue(...): buffer[3] = ...; return buffer[3]; arrayCopy communicates only for its caller . 16

  20. Communication Inlining Writer Thread Reader Thread in enqueue(...): in arrayCopy(...): in dequeue(...): @Inline arrayCopy(...): buffer[3] = ...; return buffer[3]; arrayCopy communicates only for its caller . 16

  21. Communication Inlining Writer Thread Reader Thread in enqueue(...): in dequeue(...): buffer[3] = ...; return buffer[3]; arrayCopy communicates only for its caller . 17

  22. Communication Inlining ✔ Writer Thread Reader Thread ✔ in enqueue(...): in dequeue(...): buffer[3] = ...; return buffer[3]; arrayCopy communicates only for its caller . 17

  23. Specification Constructs 18

  24. Specification Constructs A set of related methods Module (often aligned with data abstractions) 18

  25. Specification Constructs A set of related methods Module (often aligned with data abstractions) Module Which pairs of methods may communicate Specification 18

  26. Specification Constructs A set of related methods Module (often aligned with data abstractions) Module Which pairs of methods may communicate Specification Module Which communication is encapsulated Interface or visible to callers outside the module 18

  27. Specification Constructs A set of related methods Module (often aligned with data abstractions) Module Which pairs of methods may communicate Specification Module Which communication is encapsulated Interface or visible to callers outside the module Inlining Assigns communication to the caller 18

  28. Evaluation: Specification Size DaCapo Java Grande 19

  29. Evaluation: Specification Size Benchmark LOC Annotations Avrora 70,000 DaCapo Batik 190,000 Xalan 180,000 Crypt 300 LUFact 500 Java Grande MolDyn 500 MonteCarlo 1,200 RayTracer 700 Series 200 SOR 200 Sparsematmult 200 19

  30. Evaluation: Specification Size Total Ann. / Benchmark LOC Methods Annotations KLOC 2.5 Avrora 70,000 175 DaCapo 0.01 Batik 190,000 16 Xalan 180,000 90 0.5 Crypt 300 16 53 LUFact 500 15 30 Java Grande MolDyn 500 39 78 MonteCarlo 1,200 19 16 RayTracer 700 37 53 Series 200 10 50 SOR 200 14 70 Sparsematmult 200 9 45 19

  31. Evaluation: Specification Size Total Ann. / Methods % Methods Benchmark LOC Methods Annotations KLOC Annotated Annotated 2.5 0.9% Avrora 70,000 175 9,775 85 DaCapo 0.01 0.05% Batik 190,000 16 15,547 8 Xalan 180,000 90 0.5 7,854 42 0.5% Crypt 300 16 53 17 5 29% LUFact 500 15 30 29 6 21% Java Grande MolDyn 500 39 78 27 16 59% MonteCarlo 1,200 19 16 172 11 6% RayTracer 700 37 53 77 15 19% Series 200 10 50 15 6 40% SOR 200 14 70 13 5 38% Sparsematmult 200 9 45 12 4 33% 19

  32. Specification Expressiveness 20

  33. Specification Expressiveness Strengths: ✓ Concise and intuitive ✓ Encapsulation useful in many benchmarks ✓ Sensitive to error 20

  34. Specification Expressiveness Strengths: ✓ Concise and intuitive ✓ Encapsulation useful in many benchmarks ✓ Sensitive to error Limitations / Future Work: • Improve support for non-layered communication • Integrate data-centric properties to reduce specification size 20

  35. Specification Expressiveness Strengths: ✓ Concise and intuitive ✓ Encapsulation useful in many benchmarks ✓ Sensitive to error Limitations / Future Work: • Improve support for non-layered communication • Integrate data-centric properties to reduce specification size Also in the Paper: • Java annotation syntax • Formal semantics 20

  36. Outline A Code-Centric View of Shared-Memory Code-Communication Specification Language • Making Specifications Modular and Concise • Specification Language Evaluation Dynamic Specification Checker • Making Communication Checking Fast Enough • Performance Evaluation 21

  37. Fundamental Instrumentation Costs class C { int x; State x__lastWriter; 22

  38. Fundamental Instrumentation Costs class C { int x; State x__lastWriter; Store current thread and call stack write as last writer. 22

  39. Fundamental Instrumentation Costs class C { int x; State x__lastWriter; Store current thread and call stack write as last writer. Check if communication is allowed read from last writer to current reader. 22

  40. Optimizing Read Checks Mem. Check Action Ops. Same thread? 1 ✔ >30 Full check passes? ✔ Else illegal. ✘ Throw exception. 23

  41. Optimizing Read Checks Mem. Check Action Ops. Same thread? 1 ✔ >30 Full check passes? ✔ Else illegal. ✘ Throw exception. 23

  42. Optimizing Read Checks Mem. Check Action Ops. Same thread? 1 ✔ >30 Full check passes? ✔ Add pair to global memo table. Else illegal. ✘ Throw exception. 24

  43. Optimizing Read Checks Mem. Check Action Ops. Same thread? 1 ✔ Stack pair 12 in global memo table? ✔ >30 Full check passes? ✔ Add pair to global memo table. Else illegal. ✘ Throw exception. 25

  44. Optimizing Read Checks Mem. Check Action Ops. Same thread? 1 ✔ Stack pair Add writer stack ID 12 ✔ in global memo table? to reader stack’s cache . >30 Full check passes? ✔ Add pair to global memo table. Else illegal. ✘ Throw exception. 26

  45. Optimizing Read Checks Mem. Check Action Ops. Same thread? 1 ✔ Writer stack ID in 4 reader stack’s cache? ✔ Stack pair Add writer stack ID 12 ✔ in global memo table? to reader stack’s cache. >30 Full check passes? ✔ Add pair to global memo table. Else illegal. ✘ Throw exception. 27

  46. Optimizing Read Checks Mem. Check Action Ops. Same thread? 1 ✔ Writer stack ID in 4 ✔ reader stack’s cache? Stack pair Add writer stack ID 12 ✔ in global memo table? to reader stack’s cache. >30 Full check passes? ✔ Add pair to global memo table. Else illegal. ✘ Throw exception. 28

  47. Experimental Configuration 8 Java Grande, large inputs, 8 threads Benchmarks 3 DaCapo 9.12, default inputs, 8 threads 8-core 2.8GHz Intel Xeon, 10GB RAM Machine Ubuntu 8.10 HotSpot 64-bit client VM 1.6.0 JVM max heap size 8GB Average over 10 runs Data separate performance and profiling 29

  48. Execution Profile 30

  49. Execution Profile > 99.99999% of reads checked on fast paths 30

  50. Execution Profile > 99.99999% of reads checked on fast paths up to 6 billion communicating reads 30

  51. Execution Profile > 99.99999% of reads checked on fast paths up to 6 billion communicating reads ≤ 697 full stack checks 30

  52. % of reads that communicate Communicating Read Operations 100% 20% 40% 60% 80% 0% Avrora Batik Xalan Crypt LUFact MolDyn MonteCarlo RayTracer Series SOR SparseMatmult 31

  53. % of reads that communicate Communicating Read Operations 100% 20% 40% 60% 80% 0% Avrora Batik Xalan Crypt LUFact MolDyn MonteCarlo RayTracer Series SOR SparseMatmult 31

  54. Running time vs. uninstrumented Time Overhead 10x 15x 20x 25x 30x 0x 5x Avrora Batik Xalan Crypt LUFact MolDyn MonteCarlo RayTracer Series SOR SparseMatmult 32

  55. Running time vs. uninstrumented Time Overhead 10x 15x 20x 25x 30x 0x 5x Avrora Batik Xalan Crypt LUFact MolDyn MonteCarlo RayTracer Series SOR SparseMatmult 32

  56. Peak memory vs. uninstrumented Space Overhead 10x 11x 12x 0x 1x 2x 4x 5x 6x 7x 8x Avrora Batik Xalan 34.3x Crypt LUFact MolDyn MonteCarlo RayTracer Series SOR SparseMatmult 33

  57. Peak memory vs. uninstrumented Space Overhead 10x 11x 12x 0x 1x 2x 4x 5x 6x 7x 8x Avrora Batik Xalan 34.3x Crypt LUFact MolDyn MonteCarlo RayTracer Series SOR SparseMatmult 33

  58. Peak memory vs. uninstrumented Space Overhead 10x 11x 12x 0x 1x 2x 4x 5x 6x 7x 8x Avrora Batik Xalan 34.3x Crypt LUFact MolDyn MonteCarlo 0.5x RayTracer Series SOR SparseMatmult 33

  59. Summary 1. A Code-Centric View of Shared-Memory 2. Code-Communication Specification Language • Concise and modular specifications • Fit communication patterns in real programs 3. Dynamic Specification Checker • Aggressive optimization of communication checks • Debugging-level performance 34

  60. Summary 1. A Code-Centric View of Shared-Memory 2. Code-Communication Specification Language • Concise and modular specifications • Fit communication patterns in real programs 3. Dynamic Specification Checker • Aggressive optimization of communication checks • Debugging-level performance Download: www.cs.washington.edu/homes/bpw/ 34

  61. This slide intentionally not left blank 35

  62. ✔ Communication Specifications, Race Detection, Sharing Specs, Atomicity Checker Thread 1 Thread 2 Thread 3 work() { work() { ... consume() { � sync(map) { � � line = 0; � � map.put(line, x); ✔ � } ... � sync (map) { ✘ � if (line == 768) � } � sync (map) { � � line = line + 2; � � map.put(line, x); ✘ � } � � sync(map) { � � line = line + 2; � � map.put(line, x); � } int line; Map map; } // end work() 36

  63. ✔ Communication Specifications, Race Detection, Sharing Specs, Atomicity Checker Thread 1 Thread 2 Thread 3 work() { work() { ... consume() { � sync(map) { � � line = 0; � � map.put(line, x); ✔ � } ... ✔ � sync (map) { work() consume() ✘ � if (line == 768) � } ✘ work() work() � sync (map) { � � line = line + 2; � � map.put(line, x); ✘ � } � � sync(map) { � � line = line + 2; � � map.put(line, x); � } int line; Map map; } // end work() 36

Recommend


More recommend