/* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ // A CountedCompleter version of Fibonacci import java.util.concurrent.*; public abstract class CCFib extends CountedCompleter { static int sequentialThreshold; int number; int rnumber; public CCFib(CountedCompleter parent, int n) { super(parent, 1); this.number = n; } public final void compute() { CountedCompleter p; CCFib f = this; int n = number; while (n > sequentialThreshold) { new RCCFib(f, n - 2).fork(); f = new LCCFib(f, --n); } f.number = (n <= 1) ? n : seqFib(n); f.onCompletion(f); if ((p = f.getCompleter()) != null) p.tryComplete(); else f.quietlyComplete(); } static final class LCCFib extends CCFib { public LCCFib(CountedCompleter parent, int n) { super(parent, n); } public final void onCompletion(CountedCompleter caller) { CCFib p = (CCFib)getCompleter(); int n = number + rnumber; if (p != null) p.number = n; else number = n; } } static final class RCCFib extends CCFib { public RCCFib(CountedCompleter parent, int n) { super(parent, n); } public final void onCompletion(CountedCompleter caller) { CCFib p = (CCFib)getCompleter(); int n = number + rnumber; if (p != null) p.rnumber = n; else number = n; } } static long lastStealCount; public static void main(String[] args) throws Exception { int num = 45; sequentialThreshold = 5; try { if (args.length > 0) num = Integer.parseInt(args[0]); if (args.length > 1) sequentialThreshold = Integer.parseInt(args[1]); } catch (Exception e) { System.out.println("Usage: java CCFib ]"); return; } ForkJoinPool g = ForkJoinPool.commonPool(); for (int reps = 0; reps < 2; ++reps) { lastStealCount = g.getStealCount(); for (int i = 0; i < 20; ++i) { test(g, num); } System.out.println(g); } } /** for time conversion */ static final long NPS = (1000L * 1000 * 1000); static void test(ForkJoinPool g, int num) throws Exception { int ps = g.getParallelism(); long start = System.nanoTime(); CCFib f = new LCCFib(null, num); f.invoke(); long time = System.nanoTime() - start; double secs = ((double)time) / NPS; long number = f.number; System.out.print("CCFib " + num + " = " + number); System.out.printf("\tTime: %9.3f", secs); long sc = g.getStealCount(); long ns = sc - lastStealCount; lastStealCount = sc; System.out.printf(" Steals/t: %5d", ns/ps); System.out.printf(" Workers: %8d", g.getPoolSize()); System.out.println(); } // Sequential version for arguments less than threshold static final int seqFib(int n) { // unroll left only int r = 1; do { int m = n - 2; r += m <= 1 ? m : seqFib(m); } while (--n > 1); return r; } }