1 of 71

Multithreaded Programming in�Cilk�LECTURE 3

1

Charles E. Leiserson

Supercomputing Technologies Research Group

Computer Science and Artificial Intelligence Laboratory

Massachusetts Institute of Technology

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

2 of 71

Minicourse Outline

  • LECTURE 1Basic Cilk programming: Cilk keywords, performance measures, scheduling.
  • LECTURE 2Analysis of Cilk algorithms: matrix multiplication, sorting, tableau construction.
  • LABORATORYProgramming matrix multiplication in Cilk �— Dr. Bradley C. Kuszmaul
  • LECTURE 3Advanced Cilk programming: inlets, abort, speculation, data synchronization, & more.

2

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

3 of 71

LECTURE 3

3

  • Data Synchronization
  • JCilk
  • Speculative Computing
  • Conclusion
  • Under the Covers
  • Inlets
  • Abort

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

4 of 71

Operating on Returned Values

4

Programmers may sometimes wish to incorporate a value returned from a spawned child into the parent frame by means other than a simple variable assignment.

Cilk achieves this functionality using an internal function, called an inlet, which is executed as a secondary thread on the parent frame when the child returns.

x += spawn foo(a,b,c);

Example:

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

5 of 71

Semantics of Inlets

5

int max, ix = -1;

for (i=0; i<1000000; i++) {

}

sync; /* ix now indexes the largest foo(i) */

  • The inlet keyword defines a void internal function to be an inlet.
  • In the current implementation of Cilk, the inlet definition may not contain a spawn, and only the first argument of the inlet may be spawned at the call site.

update ( spawn foo(i), i );

inlet void update ( int val, int index ) {

if (idx == -1 || val > max) {

ix = index; max = val;

}

}

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

6 of 71

Semantics of Inlets

6

int max, ix = -1;

inlet void update ( int val, int index ) {

if (idx == -1 || val > max) {

ix = index; max = val;

}

}

for (i=0; i<1000000; i++) {

}

sync; /* ix now indexes the largest foo(i) */

  1. The non-spawn args to update() are evaluated.
  2. The Cilk procedure foo(i) is spawned.
  3. Control passes to the next statement.
  4. When foo(i) returns, update() is invoked.

update ( spawn foo(i), i );

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

7 of 71

Semantics of Inlets

7

int max, ix = -1;

inlet void update ( int val, int index ) {

if (idx == -1 || val > max) {

ix = index; max = val;

}

}

for (i=0; i<1000000; i++) {

update ( spawn foo(i), i );

}

sync; /* ix now indexes the largest foo(i) */

Cilk provides implicit atomicity among the threads belonging to the same frame, and thus no locking is necessary to avoid data races.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

8 of 71

Implicit Inlets

8

cilk int wfib(int n) {

if (n == 0) {

return 0;

} else {

int i, x = 1;

for (i=0; i<=n-2; i++) {

x += spawn wfib(i);

}

sync;

return x;

}

}

For assignment operators, the Cilk compiler automatically generates an implicit inlet to perform the update.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

9 of 71

LECTURE 3

9

  • Data Synchronization
  • JCilk
  • Speculative Computing
  • Conclusion
  • Under the Covers
  • Inlets
  • Abort

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

10 of 71

Computing a Product

10

p = Ai

i = 0

n

int product(int *A, int n) {

int i, p=1;

for (i=0; i<n; i++) {

p *= A[i];

}

return p;

}

Optimization: Quit early if the partial product ever becomes 0.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

11 of 71

Computing a Product

11

p = Ai

i = 0

n

int product(int *A, int n) {

int i, p=1;

for (i=0; i<n; i++) {

p *= A[i];

}

return p;

}

if (p == 0) break;

Optimization: Quit early if the partial product ever becomes 0.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

12 of 71

Computing a Product in Parallel

12

p = Ai

i = 0

n

cilk int prod(int *A, int n) {

int p = 1;

if (n == 1) {

return A[0];

} else {

p *= spawn product(A, n/2);

p *= spawn product(A+n/2, n-n/2);

sync;

return p;

}

}

How do we quit early if we discover a zero?

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

13 of 71

Cilk’s Abort Feature

13

cilk int product(int *A, int n) {

int p = 1;

inlet void mult(int x) {

p *= x;

return;

}

if (n == 1) {

return A[0];

} else {

mult( spawn product(A, n/2) );

mult( spawn product(A+n/2, n-n/2) );

sync;

return p;

}

}

1. Recode the implicit inlet to make it explicit.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

14 of 71

Cilk’s Abort Feature

14

cilk int product(int *A, int n) {

int p = 1;

inlet void mult(int x) {

p *= x;

return;

}

if (n == 1) {

return A[0];

} else {

mult( spawn product(A, n/2) );

mult( spawn product(A+n/2, n-n/2) );

sync;

return p;

}

}

2. Check for 0 within the inlet.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

15 of 71

Cilk’s Abort Feature

15

cilk int product(int *A, int n) {

int p = 1;

inlet void mult(int x) {

p *= x;

return;

}

if (n == 1) {

return A[0];

} else {

mult( spawn product(A, n/2) );

mult( spawn product(A+n/2, n-n/2) );

sync;

return p;

}

}

cilk int product(int *A, int n) {

int p = 1;

inlet void mult(int x) {

p *= x;

if (p == 0) {

abort; /* Aborts existing children, */

} /* but not future ones. */

return;

}

if (n == 1) {

return A[0];

} else {

mult( spawn product(A, n/2) );

mult( spawn product(A+n/2, n-n/2) );

sync;

return p;

}

}

2. Check for 0 within the inlet.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

16 of 71

Cilk’s Abort Feature

16

cilk int product(int *A, int n) {

int p = 1;

inlet void mult(int x) {

p *= x;

if (p == 0) {

abort; /* Aborts existing children, */

} /* but not future ones. */

return;

}

if (n == 1) {

return A[0];

} else {

mult( spawn product(A, n/2) );

mult( spawn product(A+n/2, n-n/2) );

sync;

return p;

}

}

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

17 of 71

Cilk’s Abort Feature

17

cilk int product(int *A, int n) {

int p = 1;

inlet void mult(int x) {

p *= x;

return;

}

if (n == 1) {

return A[0];

} else {

mult( spawn product(A, n/2) );

mult( spawn product(A+n/2, n-n/2) );

sync;

return p;

}

}

cilk int product(int *A, int n) {

int p = 1;

inlet void mult(int x) {

p *= x;

if (p == 0) {

abort; /* Aborts existing children, */

} /* but not future ones. */

return;

}

if (n == 1) {

return A[0];

} else {

mult( spawn product(A, n/2) );

if (p == 0) { /* Don’t spawn if we’ve */

return 0; /* already aborted! */

}

mult( spawn product(A+n/2, n-n/2) );

sync;

return p;

}

}

Implicit atomicity eases reasoning about races.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

18 of 71

LECTURE 3

18

  • Data Synchronization
  • JCilk
  • Speculative Computing
  • Conclusion
  • Under the Covers
  • Inlets
  • Abort

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

19 of 71

Min-Max Search

19

  • Two players: MAX and MIN .
  • The game tree represents all moves from the current position within a given search depth.
  • At leaves, apply a static evaluation function.
  • MAX chooses the maximum score among its children.
  • MIN chooses the minimum score among its children.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

20 of 71

Alpha-Beta Pruning

20

5

2

9

7

4

8

3

6

4

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

21 of 71

Alpha-Beta Pruning

21

5

2

9

7

4

8

3

6

4

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

22 of 71

Alpha-Beta Pruning

22

5

2

9

7

4

8

3

6

4

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

23 of 71

Alpha-Beta Pruning

23

5

2

9

7

4

8

3

6

4

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

24 of 71

Alpha-Beta Pruning

24

5

2

9

7

4

8

3

6

4

3

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

25 of 71

Alpha-Beta Pruning

25

5

2

9

7

4

8

3

6

4

3

3

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

26 of 71

Alpha-Beta Pruning

26

5

2

9

7

4

8

3

6

4

3

6

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

27 of 71

Alpha-Beta Pruning

27

5

2

9

7

4

8

3

6

4

3

6

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

28 of 71

Alpha-Beta Pruning

28

5

2

9

7

4

8

3

6

4

3

6

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

29 of 71

Alpha-Beta Pruning

29

5

6

2

9

7

4

8

3

6

4

3

6

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

30 of 71

Alpha-Beta Pruning

30

5

6

2

9

7

4

8

3

6

4

3

6

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

31 of 71

Alpha-Beta Pruning

31

5

6

2

9

7

4

8

3

6

4

3

6

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

32 of 71

Alpha-Beta Pruning

32

5

6

2

9

7

4

8

3

6

4

3

6

2

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

33 of 71

Alpha-Beta Pruning

33

5

6

2

9

2

7

4

8

3

6

4

3

6

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

34 of 71

Alpha-Beta Pruning

34

5

6

2

9

2

7

4

8

3

6

4

3

6

¸6

5

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

35 of 71

Alpha-Beta Pruning

35

5

6

2

9

2

7

4

8

3

6

4

3

6

¸6

5

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

36 of 71

Alpha-Beta Pruning

36

5

6

2

9

2

7

4

8

3

6

4

3

6

¸6

5

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

37 of 71

Alpha-Beta Pruning

37

5

6

2

9

2

7

4

8

3

6

4

3

6

¸6

5

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

38 of 71

Alpha-Beta Pruning

38

5

6

2

9

2

7

4

8

¸6

3

6

4

3

6

¸6

5

4

8

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

39 of 71

Alpha-Beta Pruning

39

5

6

2

9

2

7

4

8

3

6

4

3

6

¸6

5

¸6

4

8

Unfortunately, this heuristic is inherently serial.

IDEA: If MAX discovers a move so good that MIN would never allow that position, MAX’s other children need not be searched — beta cutoff.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

40 of 71

Parallel Min-Max Search

40

OBSERVATION: In a best-ordered tree, the degree of every internal node is either 1 or maximal.

IDEA: [Feldman-Mysliwietz-Monien 91] If the first child fails to generate a cutoff, speculate that the remaining children can be searched in parallel without wasting any work: “young brothers wait.”

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

41 of 71

Parallel Alpha-Beta (I)

41

cilk int search(position *prev, int move, int depth) {

position cur; /* Current position */

int bestscore = -INF; /* Best score so far */

int num_moves; /* Number of children */

int mv; /* Index of child */

int sc; /* Child’s score */

int cutoff = FALSE; /* Have we seen a cutoff? */

  • View from MAX’s perspective; MIN’s viewpoint can be obtained by negating scores — negamax.
  • The node generates its current position from its parent’s position prev and move.
  • The alpha and beta limits and the move list are fields of the position data structure.

#Cilk keywords used so far

1

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

42 of 71

Parallel Alpha-Beta (II)

42

inlet void get_score(int child_sc) {

child_sc = -child_sc; /* Negamax */

if (child_sc > bestscore) {

bestscore = child_sc;

if (child_sc > cur.alpha) {

cur.alpha = child_sc;

if (child_sc >= cur.beta) { /* Beta cutoff */

cutoff = TRUE; /* No need to search more */

abort; /* Terminate other children */

}

}

}

}

1

2

3

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

43 of 71

Parallel Alpha-Beta (III)

43

/* Create current position and set up for search */

make_move(prev, move, &cur);

sc = eval(&cur); /* Static evaluation */

if ( abs(sc)>=MATE || depth<=0 ) { /* Leaf node */

return (sc);

}

cur.alpha = -prev->beta; /* Negamax */

cur.beta = -prev->alpha;

/* Generate moves, hopefully in best-first order*/

num_moves = gen_moves(&cur);

3

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

44 of 71

Parallel Alpha-Beta (IV)

44

/* Search the moves */

for (mv=0; !cutoff && mv<num_moves; mv++) {

get_score( spawn search(&cur, mv, depth-1) );

if (mv==0) sync; /* Young brothers wait */

}

sync;

return (bestscore);

}

3

4

5

6

  • Only 6 Cilk keywords need be embedded in the C program to parallelize it.
  • In fact, the program can be parallelized using only 5 keywords at the expense of minimal obfuscation.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

45 of 71

LECTURE 3

45

  • Data Synchronization
  • JCilk
  • Speculative Computing
  • Conclusion
  • Under the Covers
  • Inlets
  • Abort

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

46 of 71

Mutual Exclusion

46

Cilk’s solution to mutual exclusion is no better than anybody else’s.

Cilk provides a library of spin locks declared with Cilk_lockvar.

    • To avoid deadlock with the Cilk scheduler, a lock should only be held within a Cilk thread.
    • I.e., spawn and sync should not be executed while a lock is held.

Fortunately, Cilk’s control parallelism often mitigates the need for extensive locking.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

47 of 71

Cilk’s Memory Model

47

Programmers may also synchronize through memory using lock-free protocols, although Cilk is agnostic on consistency model.

    • If a program contains no data races, Cilk effectively supports sequential consistency.
    • If a program contains data races, Cilk’s behavior depends on the consistency model of the underlying hardware.

To aid portability, the Cilk_fence() function implements a memory barrier on machines with weak memory models.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

48 of 71

Debugging Data Races

48

Cilk’s Nondeterminator debugging tool provably guarantees to detect and localize data-race bugs.

FAIL

Information localizing a data race.

PASS

Every execution produces the same result.

Input data set

“Abelian”

Cilk program

A data race occurs whenever two logically parallel threads, holding no locks in common, access the same location and one of the threads modifies the location.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

49 of 71

LECTURE 3

49

  • Data Synchronization
  • JCilk
  • Speculative Computing
  • Conclusion
  • Under the Covers
  • Inlets
  • Abort

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

50 of 71

Compiling Cilk

50

Cilk

source

cilk2c

C post-

source

source-to-source

translator

gcc

object

code

C compiler

ld

Cilk

RTS

binary

linking

loader

cilk2c translates straight C code into identical C postsource.

The cilkc compiler encapsulates the process.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

51 of 71

Cilk’s Compiler Strategy

51

SLOW

FAST

FAST

FAST

FAST

FAST

  • The fast clone is always spawned, saving live variables on Cilk’s work deque (shadow stack).
  • fast clone—serial, common-case code.
  • slow clone—code with parallel bookkeeping.

The cilk2c translator generates two “clones” of each Cilk procedure:

  • A check is made whenever a procedure returns to see if the resuming parent has been stolen.
  • The slow clone is resumed if a thread is stolen, restoring variables from the shadow stack.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

52 of 71

Compiling spawn — Fast Clone

52

suspend

parent

run child

resume

parent

remotely

cilk2c

x = spawn fib(n-1);

Cilk

source

frame->entry = 1;

frame->n = n;

push(frame);

x = fib(n-1);

if (pop()==FAILURE) {

frame->x = x;

frame->join--;

h clean up &

return to scheduler i

}

C post-

source

entry

join

n

x

y

entry

join

Cilk

deque

frame

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

53 of 71

Compiling sync — Fast Clone

53

No synchronization overhead in the fast clone!

sync;

cilk2c

Cilk

source

;

C post-

source

SLOW

FAST

FAST

FAST

FAST

FAST

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

54 of 71

Compiling the Slow Clone

54

void fib_slow(fib_frame *frame) {

int n,x,y;

switch (frame->entry) {

case 1: goto L1;

case 2: goto L2;

case 3: goto L3;

}

frame->entry = 1;

frame->n = n;

push(frame);

x = fib(n-1);

if (pop()==FAILURE) {

frame->x = x;

frame->join--;

h clean up &

return to scheduler i

}

if (0) {

L1:;

n = frame->n;

}

}

entry

join

n

x

y

entry

join

Cilk

deque

restore

program

counter

continue

same

as fast

clone

restore local

variables

if resuming

frame

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

55 of 71

Breakdown of Work Overhead

55

C

state saving

frame allocation

stealing protocol

MIPS R10000

UltraSPARC I

Pentium Pro

Alpha 21164

T1/TS

Benchmark: fib on one processor.

0

27ns

1

2

3

4

5

6

7

78ns

113ns

115ns

(circa 1997)

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

56 of 71

LECTURE 3

56

  • Data Synchronization
  • JCilk
  • Speculative Computing
  • Conclusion
  • Under the Covers
  • Inlets
  • Abort

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

57 of 71

The JCilk System

57

JCilk to Jgo

Jgo�Compiler

JVM

JCilk RTS

Fib.jcilk

Fib.jgo

  • Jgo = Java + goto.
  • The Jgo compiler was built by modifying gcj to accept goto statements so that a continuation mechanism for JCilk could be implemented.

JCilk Compiler

Fib.class

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

58 of 71

JCilk Keywords

58

cilk

spawn

sync

SYNCHED

inlet

abort

Same as Cilk, except that cilk can also modify try.

Eliminated!

JCilk leverages Java’s exception mechanism to render two Cilk keywords unnecessary.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

59 of 71

Exception Handling in Java

59

“During the process of throwing an exception, the Java virtual machine abruptly completes, one by one, any expressions, statements, method and constructor invocations, initializers, and field initialization expressions that have begun but not completed execution in the current thread. This process continues until a handler is found that indicates that it handles that particular exception by naming the class of the exception or a superclass of the class of the exception.”

— J. Gosling, B Joy, G. Steele, and G. Bracha, � Java Language Specification, 2000, pp. 219–220.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

60 of 71

Exception Handling in JCilk

60

private cilk void foo() throws IOException {

spawn A();

cilk try {

spawn B();

cilk try {

spawn C();

} catch(ArithmeticEx’n e) {

doSomething();

}

} catch(RuntimeException e) {

doSomethingElse();

}

spawn D();

doYetSomethingElse();

sync;

}

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

61 of 71

Exception Handling in JCilk

61

private cilk void foo() throws IOException {

spawn A();

cilk try {

spawn B();

cilk try {

spawn C();

} catch(ArithmeticEx’n e) {

doSomething();

}

} catch(RuntimeException e) {

doSomethingElse();

}

spawn D();

doYetSomethingElse();

sync;

}

Exception!

An exception causes all subcomputations dynamically enclosed by the catching clause to abort!

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

62 of 71

Exception Handling in JCilk

62

private cilk void foo() throws IOException {

spawn A();

cilk try {

spawn B();

cilk try {

spawn C();

} catch(ArithmeticEx’n e) {

doSomething();

}

} catch(RuntimeException e) {

doSomethingElse();

}

spawn D();

doYetSomethingElse();

sync;

}

An exception causes all subcomputations dynamically enclosed by the catching clause to abort!

ArithmeticEx’n

Nothing aborts.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

63 of 71

Exception Handling in JCilk

63

private cilk void foo() throws IOException {

spawn A();

cilk try {

spawn B();

cilk try {

spawn C();

} catch(ArithmeticEx’n e) {

doSomething();

}

} catch(RuntimeException e) {

doSomethingElse();

}

spawn D();

doYetSomethingElse();

sync;

}

An exception causes all subcomputations dynamically enclosed by the catching clause to abort!

RuntimeEx’n

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

64 of 71

Exception Handling in JCilk

64

private cilk void foo() throws IOException {

spawn A();

cilk try {

spawn B();

cilk try {

spawn C();

} catch(ArithmeticEx’n e) {

doSomething();

}

} catch(RuntimeException e) {

doSomethingElse();

}

spawn D();

doYetSomethingElse();

sync;

}

IOException

An exception causes all subcomputations dynamically enclosed by the catching clause to abort!

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

65 of 71

Exception Handling in JCilk

65

private cilk void foo() throws IOException {

spawn A();

cilk try {

spawn B();

cilk try {

spawn C();

} catch(ArithmeticEx’n e) {

doSomething();

}

} catch(RuntimeException e) {

doSomethingElse();

}

spawn D();

doYetSomethingElse();

sync;

}

RuntimeEx’n

The appropriate catch clause is executed only after all spawned methods within the corresponding try block terminate.

RuntimeEx’n

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

66 of 71

JCilk’s Exception Mechanism

66

  • JCilk’s exception semantics allow programs such as alpha-beta to be coded without Cilk’s inlet and abort keywords.
  • Unfortunately, Java exceptions are slow, reducing the utility of JCilk’s faithful extension.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

67 of 71

LECTURE 3

67

  • Data Synchronization
  • JCilk
  • Speculative Computing
  • Conclusion
  • Under the Covers
  • Inlets
  • Abort

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

68 of 71

Future Work

Adaptive computing

    • Get rid of --nproc .
    • Build a job scheduler that uses parallelism feedback to balance processor resources among Cilk jobs.

Integrating Cilk with static threads

    • Currently, interfacing a Cilk program to other system processes requires arcane knowledge.
    • Build linguistic support into Cilk for Cilk processes that communicate.
    • Develop a job scheduler that uses pipeload to allocate resources among Cilk processes.

68

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

69 of 71

Key Ideas

  • Cilk is simple: cilk, spawn, sync, SYNCHED, inlet, abort
  • JCilk is simpler
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span
  • Work & span

69

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

70 of 71

Open-Cilk Consortium

70

    • We are in the process of forming a consortium to manage, organize, and promote Cilk open-source technology.
    • If you are interested in participating, please let us know.

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3

71 of 71

ACM Symposium on Parallelism in Algorithms and Architectures

71

Cambridge, MA, USA �July 30 – August 2, 2006

SPAA 2006

© 2006 by Charles E. Leiserson

Multithreaded Programming in Cilk — LECTURE 3