--- jsr166/src/test/loops/ScalarLongSort.java 2010/09/01 07:47:27 1.3 +++ jsr166/src/test/loops/ScalarLongSort.java 2015/01/15 18:34:19 1.13 @@ -1,25 +1,43 @@ /* * 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 java.util.*; import java.util.concurrent.*; -// Based very loosely on cilksort - class ScalarLongSort { - static final long NPS = (1000L * 1000 * 1000); // time conversion + static final long NPS = (1000L * 1000 * 1000); - static int THRESHOLD; + static int THRESHOLD = -1; static final boolean warmup = true; public static void main(String[] args) throws Exception { + int procs = 0; int n = 1 << 22; - int sreps = 2; int reps = 20; + int sreps = 2; + int st = -1; + try { + if (args.length > 0) + procs = Integer.parseInt(args[0]); + if (args.length > 1) + n = Integer.parseInt(args[1]); + if (args.length > 2) + reps = Integer.parseInt(args[2]); + if (args.length > 3) + st = Integer.parseInt(args[3]); + } + catch (Exception e) { + System.out.println("Usage: java ScalarLongSort threads n reps sequential-threshold"); + return; + } + ForkJoinPool pool = (procs == 0) ? new ForkJoinPool() : + new ForkJoinPool(procs); + long[] a = new long[n]; + seqRandomFill(a, 0, n); if (warmup) { System.out.printf("Sorting %d longs, %d replications\n", n, 1); @@ -31,11 +49,10 @@ class ScalarLongSort { checkSorted(a); } - ForkJoinPool pool = new ForkJoinPool(); - // for now hardwire 8 * #CPUs leaf tasks - THRESHOLD = 1 + ((n + 7) >>> 3) / pool.getParallelism(); - // THRESHOLD = 1 + ((n + 15) >>> 4) / pool.getParallelism(); - // THRESHOLD = 1 + ((n + 31) >>> 5) / pool.getParallelism(); + if (st <= 0) // for now hardwire 8 * #CPUs leaf tasks + THRESHOLD = 1 + ((n + 7) >>> 3) / pool.getParallelism(); + else + THRESHOLD = st; System.out.printf("Sorting %d longs, %d replications\n", n, reps); for (int i = 0; i < reps; ++i) { @@ -61,7 +78,6 @@ class ScalarLongSort { } System.out.println(pool); - pool.shutdown(); } @@ -74,23 +90,24 @@ class ScalarLongSort { this.a = a; this.w = w; this.origin = origin; this.n = n; } - public void compute() { + public void compute() { int l = origin; if (n <= THRESHOLD) Arrays.sort(a, l, l+n); else { // divide in quarters to ensure sorted array in a not w - SubSorter rs; int h = n >>> 1; int q = n >>> 2; int u = h + q; - (rs = new SubSorter - (new Sorter(a, w, l+h, q), - new Sorter(a, w, l+u, n-u), - new Merger(a, w, l+h, q, l+u, n-u, l+h, null))).fork(); - (new SubSorter - (new Sorter(a, w, l, q), - new Sorter(a, w, l+q, h-q), - new Merger(a, w, l, q, l+q, h-q, l, null))).compute(); + SubSorter rs = new SubSorter + (new Sorter(a, w, l+h, q), + new Sorter(a, w, l+u, n-u), + new Merger(a, w, l+h, q, l+u, n-u, l+h, null)); + rs.fork(); + Sorter rl = new Sorter(a, w, l+q, h-q); + rl.fork(); + (new Sorter(a, w, l, q)).compute(); + rl.join(); + (new Merger(a, w, l, q, l+q, h-q, l, null)).compute(); rs.join(); new Merger(w, a, l, h, l+h, n-h, l, null).compute(); } @@ -115,7 +132,7 @@ class ScalarLongSort { static final class Merger extends RecursiveAction { final long[] a; final long[] w; final int lo; final int ln; final int ro; final int rn; final int wo; - final Merger next; + Merger next; Merger(long[] a, long[] w, int lo, int ln, int ro, int rn, int wo, Merger next) { this.a = a; this.w = w; @@ -130,9 +147,8 @@ class ScalarLongSort { * and finding index of right closest to split point. * Uses left-spine decomposition to generate all * merge tasks before bottomming out at base case. - * */ - public void compute() { + public final void compute() { Merger rights = null; int nleft = ln; int nright = rn; @@ -155,7 +171,13 @@ class ScalarLongSort { nright = rh; } - // Base case -- merge left and right + merge(nleft, nright); + if (rights != null) + collectRights(rights); + + } + + final void merge(int nleft, int nright) { int l = lo; int lFence = lo + nleft; int r = ro; @@ -172,16 +194,20 @@ class ScalarLongSort { w[k++] = a[l++]; while (r < rFence) w[k++] = a[r++]; + } - while (rights != null) { - rights.join(); - rights = rights.next; + static void collectRights(Merger rt) { + while (rt != null) { + Merger next = rt.next; + rt.next = null; + if (rt.tryUnfork()) rt.compute(); else rt.join(); + rt = next; } } } - static void checkSorted(long[] a) { + static void checkSorted(long[] a) { int n = a.length; for (int i = 0; i < n - 1; i++) { if (a[i] > a[i+1]) { @@ -204,8 +230,12 @@ class ScalarLongSort { this.array = array; this.lo = lo; this.hi = hi; } public void compute() { - if (hi - lo <= THRESHOLD) - seqRandomFill(array, lo, hi); + if (hi - lo <= THRESHOLD) { + long[] a = array; + ThreadLocalRandom rng = ThreadLocalRandom.current(); + for (int i = lo; i < hi; ++i) + a[i] = rng.nextLong(); + } else { int mid = (lo + hi) >>> 1; RandomFiller r = new RandomFiller(array, mid, hi); @@ -215,6 +245,4 @@ class ScalarLongSort { } } } - - }