5. The Big Idea
• Don’t specify what operations run in parallel
• Difficult and depends on target
• Specify the semantic ordering constraints only
• Easier and depends only on application
5
6. Exactly Two Sources of Ordering
Requirements
• Producer must execute before consumer
• Controller must execute before controllee
6
7. Outline
• The Concurrent Collections (CnC) Model
• Features
• Constructs
• CnC Scala – Example
• Implementation
• Results
7
8. The CnC model
• Programmer defines semantic dependences
• Ordering constraints between computational units
• Code in computation unit is standard serial code
• Runtime takes care of
• Executing the computational units
• Extracting parallelism in the application
8
9. CnC Constructs - Steps
(step)
• Computational unit of a CnC program
• Stateless
• Side-effect free
• Functional with respect to inputs
9
10. CnC Constructs – Data Items
[in_item]
(step) [out_item]
• Data units are called Item Collection
• Means of communication between steps
• Mapping of data tags to items
• Items can only be retrieved by their tags
• Dynamic single assignment
10
11. CnC Constructs - Control
<tag>
[in_item]
(step) [out_item]
• Tag Collections are control units
• Used to execute (prescribe) steps
• A CnC step will not launch until its tag has been put
11
12. CnC Constructs - Environment
env
<tag>
env
env
[in_item]
(step) [out_item]
• A driver which encapsulates the CnC Graph
• Provides inputs to and consumes outputs
from the CnC Graph
12
13. Exactly Two Sources of Ordering
Requirements
• Producer must execute before consumer
• Controller must execute before controllee
Producer - Consumer Controller - Controllee
<tag1>
(prod) [C1]
(cons)
(C-er)
(C-ee)
13
14. Outline
• The CnC Model
• CnC-Scala
• Build Model
• Capitalize-Words Example
• Step Code
• Implementation
• Results
14
15. CnC-Scala
• Written in pure Scala
• uses continuations compiler plugin
• Only dependency – jsr-166y.jar
• comes bundled with java 7
• Distribution with examples available at:
• http://cnc-scala.rice.edu/
15
18. Generated Code Example
1. trait SplitStep extends Step {
2.
3. // Optional to provide an implementation
4. def createDependences(
5. tag: java.lang.String,
6. inInput: InputCollection[java.lang.String, java.lang.String],
7. dependenceManager: DependenceManager
8. ): Unit = {}
9.
10. // User must provide an implementation for this method
11. def compute(
12. tag: java.lang.String,
13. inInput: InputCollection[java.lang.String, java.lang.String],
14. outToken: TagCollection[java.lang.String],
15. outWords: OutputCollection[java.lang.String, java.lang.String]
16. ): Unit@cpsParam[Any, Any]
17. }
18
19. User Step Code
1. class UserSplitStep extends SplitStep {
2.
3. // User must provide an implementation for this method
4. def compute(
5. tag: java.lang.String,
6. inInput: InputCollection[java.lang.String, java.lang.String],
7. outToken: TagCollection[java.lang.String],
8. outWords: OutputCollection[java.lang.String, java.lang.String]
9. ): Unit@cpsParam[Any, Any] = {
10. val inString = inInput.get(tag)
11. for ((token, index) <- inString.split(" +").view.zipWithIndex) {
12. val newTag = tag + ":" + index
13. outWords.put(newTag, token)
14. outToken.put(newTag)
15. } } }
19
20. User Main
1. object SplitCapitalizeMain extends CncScalaApp {
2. // Instantiate Steps
3. val splitStep = new UserSplitStep()
4. val capitalizeStep = new UserCapitalizeStep()
5. val graph = new SplitCapitalizeGraph(splitStep, capitalizeStep)
6.
7. graph.run(new Runnable() {
8. def run(): Unit = {
9. // populate data from environment to collections
10. val tag = "1"
11. graph.input.put(tag, "hello world")
12. graph.data.put(tag)
13. }
14. })
15. // read results
16. graph.result.dump(System.out)
17. }
20
21. Outline
• The CnC Model
• CnC-Scala
• Implementation
• Data-driven futures
• Continuations
• Results
21
22. Implementation
• Tag Collections
• Spawn new tasks run step code
• Item Collections
• Use concurrent maps with user defined tag types as keys
and data-driven futures (DDF) as values
• What to do when get() has unavailable items?
• Create continuations
• When value becomes available…
• DDFs resume continuations
22
23. Data-driven futures
• Separation of classical “futures” into data and
control parts
• Consumers can eagerly register on the DDF even
before we know about the producer
• i.e., lazily attaches a producer to an item
• When item is produced, all previously registered
consumers are notified
• Subsequent consumers always get the value
immediately
23
24. Continuations
• Represents rest of the computation from a given
point in the program
• Allows
• suspending current execution state
• resume from that point later
• We need only delimited one-shot continuations
• Scala has shift-reset!
24
25. Benefits of using continuations
• No re-execution of code
• Allow arbitrary (data-dependent) gets
• Threads never block
• No extra threads created
25
26. Scala Continuation example
1. object Main {
2. def main(args: Array[String]) {
3. println("A. Main starts")
4. var continuation: (Unit) => Any = null
Output:
5. reset { // delimit boundary start
6. println("B. Entered reset")
7. shift[Unit, Any, Unit] { A. Main starts
8. delimCont => B. Entered reset
9. println("C. Entered shift") C. Entered shift
10. continuation = delimCont D. Inside shift
F. Outside reset
11. println("D. Inside shift")
G. Calling cont.
12. }
E. After shift
13. println("E. After shift")
H. Main ends
14. } // delimit boundary end
15. println("F. Outside reset")
16. println("G. Calling cont.")
17. continuation()
18. println("H. Main ends")
19. }
20. } 26
27. CnC-Scala Runtime - step
• Tag Collection step prescription
• Wrap each step.compute() in a reset
// some preparation
reset {
step.compute(tag, inputs, outputs)
}
// book-keeping logic based on
// whether continuation was stored
// or execution completed normally
27
28. CnC-Scala Runtime - get
• If item is available return it
• Else store continuation
get(tag: TagType): ItemType = {
if (itemAvailable)
return item
else
shift { continuation =>
// store continuation
}
// when cont resumes, item is available
return item
}
28
29. CnC-Scala Runtime - put
• Store item
• Resume waiting continuations
put(tag: TagType, item: ItemType) {
// store item into DDF
// resume ALL waiting continuations
}
29
30. Outline
• The CnC Model
• CnC-Scala
• Implementation
• Results
30
31. CnC-Scala Results
• 12-core (two hex-cores) 2.8 GHz Intel Westmere
SMP
• 48 GB memory, running Red Hat Linux (RHEL 6.0)
• Hotspot JDK 1.7
• Scala version 2.9.1-1
• CnC-Scala 0.1.2
• Arithmetic mean of last thirty iterations from
hundred iterations on ten separate JVM invocations
31
35. CnC Features
• Coordination language
• Dynamic light-weight task based
• Single assignment
• Deterministic
• Race free
35
36. Summary
• CnC exposes more potential parallelism
• Development is productive
• User declaratively defines dependences and
writes only serial code
• runtime hides all the difficulties with using low-
level techniques
• result is deterministic and independent of number
of threads
36