divide and conquer parallelism with the fork/join framework · divide and conquer parallelism with...

54

Upload: vodung

Post on 07-May-2019

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform
Page 2: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Divide and Conquer Parallelismwith the Fork/Join FrameworkMark Reinhold (@mreinhold)Chief Architect, Java Platform Group2011/7/7

Page 3: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

1970 1975 1980 1985 1990 1995 2000 2005 2010

1

10

100

1,000

10,000

1,000,000

100,000

10,000000

Page 4: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

1970 1975 1980 1985 1990 1995 2000 2005 2010

1

10

100

1,000

10,000

1,000,000

100,000

10,000000

Clock (MHz)

Page 5: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

1970 1975 1980 1985 1990 1995 2000 2005 2010

1

10

100

1,000

10,000

1,000,000

100,000

10,000000

Clock (MHz)

Transistors (1,000s)

Page 6: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform
Page 7: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Niagara 1 (2005)8 x 4 = 32

Page 8: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Niagara 1 (2005)8 x 4 = 32

Niagara 2 (2007)8 x 8 = 64

Page 9: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Niagara 1 (2005)8 x 4 = 32

Niagara 2 (2007)8 x 8 = 64

Rainbow Falls16 x 8 = 128

Page 10: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Trends

Page 11: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Trends

One core Threads were for asynchrony, not parallelism —

Page 12: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Trends

One core Threads were for asynchrony, not parallelism —

Some cores Coarse-grained parallelism usually enough• Application-level requests were good task boundaries

• Thread pools were a reasonable scheduling mechanism

Page 13: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Trends

One core Threads were for asynchrony, not parallelism —

Some cores Coarse-grained parallelism usually enough• Application-level requests were good task boundaries

• Thread pools were a reasonable scheduling mechanism

Many cores Coarse-grained parallelism insufficient• Application-level requests won’t keep cores busy

• Shared work queues become a bottleneck

Page 14: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Trends

One core Threads were for asynchrony, not parallelism —

Some cores Coarse-grained parallelism usually enough• Application-level requests were good task boundaries

• Thread pools were a reasonable scheduling mechanism

Many cores Coarse-grained parallelism insufficient• Application-level requests won’t keep cores busy

• Shared work queues become a bottleneck

Need to find finer-grained, CPU-intensive parallelism

Page 15: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

The key challenges for multicore code

Page 16: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

The key challenges for multicore code

(1) Decompose problems into parallelizable work units

Page 17: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

The key challenges for multicore code

(1) Decompose problems into parallelizable work units

(2) Continue to meet (1) as the number of cores increases

Page 18: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet

Page 19: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet

Many point solutions:

Page 20: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet

Many point solutions:

• Work queues + thread pools

Page 21: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet

Many point solutions:

• Work queues + thread pools

• Divide & conquer (fork/join)

Page 22: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet

Many point solutions:

• Work queues + thread pools

• Divide & conquer (fork/join)

• Bulk data operations (select/map/reduce)

Page 23: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet

Many point solutions:

• Work queues + thread pools

• Divide & conquer (fork/join)

• Bulk data operations (select/map/reduce)

• Actors

Page 24: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet

Many point solutions:

• Work queues + thread pools

• Divide & conquer (fork/join)

• Bulk data operations (select/map/reduce)

• Actors

• Software transactional memory (STM)

Page 25: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet

Many point solutions:

• Work queues + thread pools

• Divide & conquer (fork/join)

• Bulk data operations (select/map/reduce)

• Actors

• Software transactional memory (STM)

• GPU-based SIMD-style computation

Page 26: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Divide & conquer

Page 27: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Divide & conquer

Page 28: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Divide & conquer

Page 29: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Divide & conquer

Page 30: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Divide & conquer

Page 31: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Divide & conquer

Page 32: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Result solve(Problem p) { if (p.size() < SEQUENTIAL_THRESHOLD) { return p.solveSequentially(); } else { int m = n / 2; Result left, right; INVOKE-IN-PARALLEL { left = solve(p.leftHalf()); right = solve(p.rightHalf()); } return combine(left, right); }}

Page 33: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform
Page 34: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

class Student { String name; int gradYear; double score;}

Page 35: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

class Student { String name; int gradYear; double score;}

List<Student> students = ...;

Page 36: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

double max = Double.MIN_VALUE;for (Student s : students) { if (s.gradYear == 2010) max = Math.max(max, s.score);}

class Student { String name; int gradYear; double score;}

List<Student> students = ...;

Page 37: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

double max = Double.MIN_VALUE;for (Student s : students) { if (s.gradYear == 2010) max = Math.max(max, s.score);}

return max; }

class MaxFinder {

final List<Student> students;

MaxFinder(List<Student> ls) { students = ls; }

double find() {

Page 38: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

double max = Double.MIN_VALUE;for (Student s : students) { if (s.gradYear == 2010) max = Math.max(max, s.score);}

return max; }

MaxFinder subFinder(int s, int e) { return new MaxFinder(students.subList(s, e)); }

class MaxFinder {

final List<Student> students;

MaxFinder(List<Student> ls) { students = ls; }

double find() {

Page 39: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform
Page 40: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

// Fork/join frameworkimport java.util.concurrent.*;

Page 41: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

// Fork/join frameworkimport java.util.concurrent.*;

class MaxFinderTask extends RecursiveAction{

final MaxFinder maxf; double result;

MaxFinderTask(MaxFinder mf) { maxf = mf; }

Page 42: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

class MaxFinderTask extends RecursiveAction{

protected void compute() { int n = maxf.students.size(); if (n < SEQUENTIAL_THRESHOLD) { result = maxf.find(); } else { int m = n / 2; MaxFinderTask left = new MaxFinderTask(maxf.subFinder(0, m)); MaxFinderTask right = new MaxFinderTask(maxf.subFinder(m, n)); invokeAll(left, right); result = Math.max(left.result, right.result); } }

Page 43: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

class MaxFinder {

double find() { double max = Double.MIN_VALUE; for (Student s : students) { if (s.gradYear == 2010) max = Math.max(max, s.score); } return max; }

MaxFinder subFinder(int s, int e) { return new MaxFinder(students.subList(s, e)); }

Page 44: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

class MaxFinder {

double find() {

double parallelFind() { MaxFinderTask mft = new MaxFinderTask(this); ForkJoinPool pool = new ForkJoinPool(); pool.invoke(mft); return mft.result; }

MaxFinder subFinder(int s, int e) { return new MaxFinder(students.subList(s, e)); }

... }

Page 45: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

protected void compute() { int n = maxf.students.size(); if (n < SEQUENTIAL_THRESHOLD) { result = maxf.find(); } else { int m = n / 2; MaxFinderTask left = new MaxFinderTask(maxf.subFinder(0, m)); MaxFinderTask right = new MaxFinderTask(maxf.subFinder(m, n)); invokeAll(left, right); result = Math.max(left.result, right.result); } }

class MaxFinderTask extends RecursiveAction{

Page 46: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

protected void compute() { int n = maxf.students.size(); if (n < SEQUENTIAL_THRESHOLD) { result = maxf.find(); } else { int m = n / 2; MaxFinderTask left = new MaxFinderTask(maxf.subFinder(0, m)); MaxFinderTask right = new MaxFinderTask(maxf.subFinder(m, n)); invokeAll(left, right); result = Math.max(left.result, right.result); } }

// ???

class MaxFinderTask extends RecursiveAction{

Page 47: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Performance considerations

Page 48: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Performance considerations• Choosing the sequential threshold

– Smaller tasks increase parallelism

– Larger tasks reduce coordination overhead

– Ultimately you must profile your code

Page 49: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Performance considerations• Choosing the sequential threshold

– Smaller tasks increase parallelism

– Larger tasks reduce coordination overhead

– Ultimately you must profile your code

Sequential threshold 500K 50K 5K 500 50

Dual Xeon HT (4) 0.88 3.02 3.20 2.22 0.43

8-way Opteron (8) 1.00 5.29 5.73 4.53 2.03

8-core Niagara (32) 0.98 10.46 17.21 15.34 6.49

Page 50: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Performance considerations

Page 51: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Performance considerations• The fork/join framework minimizes per-task overhead

for compute-intensive tasks– Not recommended for tasks that mix CPU and I/O activity

Page 52: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

Performance considerations• The fork/join framework minimizes per-task overhead

for compute-intensive tasks– Not recommended for tasks that mix CPU and I/O activity

• A portable way to express many parallel algorithms– Code is independent of execution topology

– Reasonably efficient for a wide range of core counts

– Library-managed parallelism

Page 53: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform

No silver bullet—but many useful tools

Many point solutions:

• Work queues + thread pools

• Divide & conquer (fork/join)

• Bulk data operations (select/map/reduce)

• Actors

• Software transactional memory (STM)

• GPU-based SIMD-style computation

Page 54: Divide and Conquer Parallelism with the Fork/Join Framework · Divide and Conquer Parallelism with the Fork/Join Framework Mark Reinhold (@mreinhold) Chief Architect, Java Platform