Fork Join (BeJUG 2012)

2,726 views

Published on

Introduction to JDK7's Fork/Join framework. Present on May 3 2012 at the Belgian Java User Group (BeJUG). For more information see: http://www.bejug.org/confluenceBeJUG/display/BeJUG/ForkJoin+and+Akka

Demo code can be found at http://bit.ly/bejug-fj

Published in: Technology, News & Politics
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,726
On SlideShare
0
From Embeds
0
Number of Embeds
72
Actions
Shares
0
Downloads
9
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Fork Join (BeJUG 2012)

  1. 1. ForkJoin@Sander_Mak
  2. 2. AboutCoding at ( ) Writing Blog @ branchandbound.net Speaking
  3. 3. AgendaForkJoin Setting the scene ForkJoin API & Patterns Comparisons & Future break Akka Introduction Actors Async IO
  4. 4. Problem?
  5. 5. Problem?
  6. 6. Problem?
  7. 7. Problem?
  8. 8. Problem?Architectural mismatch
  9. 9. Problem?So let the compiler/runtime solve it!
  10. 10. Problem?So let the compiler/runtime solve it! n  <  2 nif  (n  <  2)    {  return  n;  }else    {  return  fib(n  -­‐  1)  +  fib(n  -­‐  2);  }
  11. 11. Problem?So let the compiler/runtime solve it! Unfortunately not in , but feasible in pure functional languages like
  12. 12. First attempt        public  static  int  fib(final  int  n)  {                if  (n  <  2)  {  return  n;  }                else  {                        final  int[]  t1  =  {0},  t2  =  {0};                                                Thread  thread1  =  new  Thread()  {                                public  void  run()  {                                        t1[0]  =  fib(n  -­‐  1);                                }  };                        Thread  thread2  =  new  Thread()  {                                public  void  run()  {                                                t2[0]  =  fib(n  -­‐  2);                                }  };                        thread1.start();  thread2.start();                        thread1.join();  thread2.join();                        return  t1[0]  +  t2[0];                }        } if  (n  <  2)    {  return  n;  } else    {  return  fib(n  -­‐  1)  +  fib(n  -­‐  2);  }
  13. 13. ThreadsThreads are mostly waitingImprove with threadpooling but not by much starvationWhat if we sum in a new thread? synchronization visibility issues (Java Memory Model)
  14. 14. ForkJoinFork:Recursively decompose Result = 3large task into subtasks Fib(4)Join: Fib(3) Fib(2)Await results ofrecursive tasksand combine Fib(2) Fib(1) Fib(1) Fib(0) Fib(1) Fib(0)
  15. 15. ForkJoinIntroducing: ForkJoinPool java.util.concurrent. java.util.concurrent.ForkJoinTask ForkJoinTask RecursiveAction RecursiveTask ForkJoinPool:void execute (ForkJoinTask<?>)T invoke (ForkJoinTask<T>)    
  16. 16. ForkJoincompute(problem)  {    if  (problem.size  <  threshold)        directlySolve(problem)    else  {        do-­‐forked  {              leftResult    =  compute(left(problem))              rightResult  =  compute(right(problem))        }        join(leftResult,  rightResult)        return  combine(leftResult,  rightResult)    }} Keep overhead down: sequential cutoff
  17. 17. ForkJoinPoolImplements ExecutorServiceAutosize workers (overridable)Work queue per worker Work-stealing between queues
  18. 18. ForkJoinPoolWork stealing
  19. 19. ForkJoinPool Work stealing1
  20. 20. ForkJoinPool Work stealing1
  21. 21. ForkJoinPool Work stealing231
  22. 22. ForkJoinPool Work stealing st ol en3 2
  23. 23. ForkJoinPool Work stealing3 2
  24. 24. ForkJoinPool Work stealing4 65 73 2
  25. 25. ForkJoinPool Work stealing4 sto len5 7 6
  26. 26. ForkJoinPool Work stealing48 10 12 sto len9 11 135 7 6
  27. 27. ForkJoinPoolScalability
  28. 28. Patterns #1 Problem structureAcyclic CPU Bound - I/O upfront - No webcrawlers please...
  29. 29. Patterns #2 Sequential cutoff Guidelines compute(problem)  {> 100 and < 10.000    if  (problem.size  <  threshold)‘basic computational        directlySolve(problem)    else  {steps’        do-­‐forked  {              ...Experiment and tune        }        join  ...    }Never lock/synchronize }
  30. 30. Patterns #3 Fork once, fool me twice Why? left.fork() rightResult  =  right.compute() leftResult  =  left.join()Implementation return  leftResult  +  rightResultspecificAvoids overhead left.fork()Especially on smallish leftResult  =  left.join() rightResult  =  right.compute()tasks return  leftResult  +  rightResult
  31. 31. Patterns #4 Use convenience methodsinvoke invokeAllfjTask.invoke(); invokeAll(fjTask1,  fjTask2,//  Equivalent  to      fjTaskN);fjTask.fork();fjTask.join(); //  Or://  But  always  tries  execution//  in  current  thread  first! invokeAll(collectionOfTasks);
  32. 32. Demo2.797.245 world cities (Maxmind.com)Demo 1: simple searchDemo 2: lat/long bounded
  33. 33. DemoSearch range: i.e. 0.4°
  34. 34. ForkJoin & Java EE ForkJoinPool creates threads Illegal in EJBs CDI/Servlet is a gray area JCA/WorkManager could work @Asynchronous as alternativeBut: Java EE7 may contain javax.util.concurrent
  35. 35. Comparison ExecutorServiceThread pooling (bounded orunbounded)Single work queue (no workstealing)Coarse-grained independent tasksBlocking I/O ok
  36. 36. Comparison MapReduceEnvironment Single JVM ClusterModel Recursive forking Often single mapScales with Cores/CPUs NodesWorker Workstealing No inter-nodeinteraction communication
  37. 37. CriticismComplex implementation (uses sun.misc.Unsafe) Scalability > 100 cores? Questionable assumption: 1-1 mapping worker thread to core
  38. 38. CriticismComplex implementation (uses sun.misc.Unsafe) Scalability > 100 cores? Questionable assumption: 1-1 mapping worker thread to core Too low-level
  39. 39. FutureInfoQ: “What is supported out of the box?” “Almost nothing". We chickened out; we are not going to release the layers on top of this That means that right now, people who are using this framework are going to be the people who actually get into this parallel recursive decomposition and know how to use it.
  40. 40. FutureJDK 8 plans Parallel collections Depends on Project Lambda CountedCompleter for I/OSome already available in jsr166extra
  41. 41. Futureint  findCities(List<String>  cities,  String  query)  {      Pattern  p  =  Pattern.compile(query)      return  cities.parallel()                                .filter(c  =>  p.matcher(c).matches());        } int  findNearestCities(List<String>  lines,  int  lat,  int  lng)  {      return  lines.parallel()                              .map(c  =>  toCity(c))                              .filter(c  =>  c.isNear(lat,  lng))                              .sort(); }
  42. 42. Questions? Code @ bit.ly/bejug-fj

×