--- jsr166/src/test/loops/DynamicLeftSpineFib.java 2009/11/02 23:42:46 1.5 +++ jsr166/src/test/loops/DynamicLeftSpineFib.java 2015/01/15 18:34:19 1.16 @@ -1,21 +1,19 @@ /* * 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/licenses/publicdomain + * http://creativecommons.org/publicdomain/zero/1.0/ */ -//import jsr166y.*; import java.util.*; import java.util.concurrent.*; public final class DynamicLeftSpineFib extends RecursiveAction { - // Performance-tuning constant: static long lastStealCount; public static void main(String[] args) throws Exception { int procs = 0; - int num = 43; + int num = 45; try { if (args.length > 0) procs = Integer.parseInt(args[0]); @@ -23,21 +21,22 @@ public final class DynamicLeftSpineFib e num = Integer.parseInt(args[1]); } catch (Exception e) { - System.out.println("Usage: java DynamicLeftSpineFib []"); + System.out.println("Usage: java DynamicLeftSpineFib []"); return; } - for (int reps = 0; reps < 2; ++reps) { - ForkJoinPool g = (procs == 0) ? - new ForkJoinPool() : + ForkJoinPool g = (procs == 0) ? new ForkJoinPool() : new ForkJoinPool(procs); lastStealCount = g.getStealCount(); - for (int i = 0; i < 10; ++i) { + for (int i = 0; i < 20; ++i) { test(g, num); } System.out.println(g); g.shutdown(); + if (!g.awaitTermination(10, TimeUnit.SECONDS)) + throw new Error(); + Thread.sleep(1000); } } @@ -49,7 +48,7 @@ public final class DynamicLeftSpineFib e long time = System.currentTimeMillis() - start; double secs = ((double)time) / 1000.0; long result = f.getAnswer(); - System.out.print("DynamicLeftSpineFib " + num + " = " + result); + System.out.print("DLSFib " + num + " = " + result); System.out.printf("\tTime: %7.3f", secs); long sc = g.getStealCount(); long ns = sc - lastStealCount; @@ -59,7 +58,6 @@ public final class DynamicLeftSpineFib e System.out.println(); } - // Initialized with argument; replaced with result int number; DynamicLeftSpineFib next; @@ -71,31 +69,61 @@ public final class DynamicLeftSpineFib e int getAnswer() { return number; } + public void compute() { + number = fib(number); + } - public final void compute() { - int n = number; - if (n > 1) { - DynamicLeftSpineFib rt = null; - while (n > 1 && getSurplusQueuedTaskCount() <= 3) { - (rt = new DynamicLeftSpineFib(n - 2, rt)).fork(); - n -= 1; + static final int fib(int n) { + if (n <= 1) + return n; + int r = 0; + DynamicLeftSpineFib rt = null; + while (getSurplusQueuedTaskCount() <= 3) { + int m = n - 2; + n -= 1; + if (m <= 1) { + r += m; + if (n > 1) { + r += n - 2; + n -= 1; + } + break; } - int r = seqFib(n); - while (rt != null) { - if (rt.tryUnfork()) rt.compute(); else rt.helpJoin(); + (rt = new DynamicLeftSpineFib(m, rt)).fork(); + } + if (n <= 1) + r += n; + else + r += seqFib(n - 2) + fib(n - 1); + if (rt != null) + r += collectRights(rt); + return r; + } + + static final int collectRights(DynamicLeftSpineFib rt) { + int r = 0; + while (rt != null) { + DynamicLeftSpineFib rn = rt.next; + rt.next = null; + if (rt.tryUnfork()) + r += fib(rt.number); + else { + rt.join(); r += rt.number; - rt = rt.next; } - number = r; + rt = rn; } + return r; } // Sequential version for arguments less than threshold - static int seqFib(int n) { - if (n <= 1) - return n; - else - return seqFib(n-1) + seqFib(n-2); + 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; } }